在avro文件中存储空值

mba*_*a12 7 java avro avro-tools

我有一些看起来像这样的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": "testuser@test.com",
    "lockedQuery": false,
    "lockedByUsername": null
  }
Run Code Online (Sandbox Code Playgroud)

我可以将lockedQuery null值添加到GenericRecord对象而不会出现问题.

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

但是,稍后当我尝试将该GenericRecord对象写入avro文件时,我得到一个空指针异常.

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
}
Run Code Online (Sandbox Code Playgroud)

当我运行该代码时,我得到以下异常.有关如何将空值处理成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)
Run Code Online (Sandbox Code Playgroud)

编辑:这是MyAvroRecord

public class MyAvroRecord {
    long id;
    String name;
    String type;
    Date timestamp;
    Date lastModifcationDate;
    String lastModifiedUsername;
    Boolean lockedQuery;
Run Code Online (Sandbox Code Playgroud)

Vla*_*roz 18

为了能够将Avro字段设置为null您,应该在Avro架构中允许这样做,方法是添加null一个可能的字段类型.看看Avro文档中的示例:

{
  "type": "record",
  "name": "MyRecord",
  "fields" : [
    {"name": "userId", "type": "long"},              // mandatory field
    {"name": "userName", "type": ["null", "string"]} // optional field 
  ]
}
Run Code Online (Sandbox Code Playgroud)

这里userName声明为复合类型,可以是null或者string.这种定义允许将userName字段设置为null.由于对比度userId只能包含长值,因此尝试设置userId为null将导致NullPointerException.

  • 如何在不使用模式文件的情况下在Java界面中完成? (2认同)
  • 您可以使用SchemaBuilder通过设置字段的类型来做到这一点,如下所示:.type(SchemaBuilder.unionOf()。nullType()。and()。stringType()。endUnion())` (2认同)

小智 7

我也有这个问题,现在已经解决了。

我在Apache Avro@Nullable中找到注释来声明该字段可为空。

所以,在这个例子中,我们应该

import org.apache.avro.reflect.Nullable;

public class MyAvroRecord {
    long id;
    String name;
    String type;
    Date timestamp;
    Date lastModifcationDate;
    String lastModifiedUsername;
    @Nullable
    Boolean lockedQuery;
}
Run Code Online (Sandbox Code Playgroud)