web-dev-qa-db-ja.com

Avroファイルへのnull値の格納

次のようなJSONデータがあります。

  {
    "id": 1998983092,
    "name": "Test Name 1",
    "type": "search string",
    "creationDate": "2017-06-06T13:49:15.091+0000",
    "lastModificationDate": "2017-06-28T14:53:19.698+0000",
    "lastModifiedUsername": "[email protected]",
    "lockedQuery": false,
    "lockedByUsername": null
  }

私は問題なくlockedQuery null値をGenericRecordオブジェクトに追加できます。

GenericRecord record = new GenericData.Record(schema);
if(json.isNull("lockedQuery")){
    record.put("lockedQuery", null);
} 

ただし、後でそのGenericRecordオブジェクトをavroファイルに書き込もうとすると、nullポインター例外が発生します。

File file = new File("~/test.arvo");
DatumWriter<GenericRecord> datumWriter = new GenericDatumWriter<>(schema);
DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<>(datumWriter);
dataFileWriter.create(schema, file);
for(GenericRecord record: masterList) {
    dataFileWriter.append(record); // NULL POINTER HERE
}

そのコードを実行すると、次の例外が発生します。 null値をAvroファイルに処理する方法に関するヒントは、高く評価されています。前もって感謝します。

Java.lang.NullPointerException: null of boolean in field lockedQuery of 
com.mydomain.test1.domain.MyAvroRecord
Exception in thread "main" Java.lang.RuntimeException: 
org.Apache.avro.file.DataFileWriter$AppendWriteException: 
Java.lang.NullPointerException: null of boolean in field lockedQuery of 
com.mydomain.test1.domain.MyAvroRecord
at com.mydomain.avro.App.main(App.Java:198)
Caused by: org.Apache.avro.file.DataFileWriter$AppendWriteException: 
Java.lang.NullPointerException: null of boolean in field lockedQuery of 
com.mydomain.test1.domain.MyAvroRecord
at org.Apache.avro.file.DataFileWriter.append(DataFileWriter.Java:308)

編集:ここにMyAvroRecordがあります

public class MyAvroRecord {
    long id;
    String name;
    String type;
    Date timestamp;
    Date lastModifcationDate;
    String lastModifiedUsername;
    Boolean lockedQuery;
9
mba12

Avroフィールドをnullに設定できるようにするには、フィールドの可能なタイプの1つとしてnullを追加して、Avroスキーマでこれを許可する必要があります。 Avroのドキュメントの例をご覧ください。

{
  "type": "record",
  "name": "MyRecord",
  "fields" : [
    {"name": "userId", "type": "long"},              // mandatory field
    {"name": "userName", "type": ["null", "string"]} // optional field 
  ]
}

ここでuserNameは、nullまたはstringのいずれかの複合型として宣言されています。この種類の定義では、userNameフィールドをnullに設定できます。対照的に、userIdには長い値しか含めることができないため、userIdをnullに設定しようとすると、NullPointerExceptionになります。

17
Vladimir Kroz

私にもこの問題があり、解決しました。

Apache Avro@Nullableアノテーションを見つけて、フィールドがnull可能であることを宣言しました。

したがって、この例では、

import org.Apache.avro.reflect.Nullable;

public class MyAvroRecord {
    long id;
    String name;
    String type;
    Date timestamp;
    Date lastModifcationDate;
    String lastModifiedUsername;
    @Nullable
    Boolean lockedQuery;
}
2
soymsk