Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在avro文件中存储空值_Java_Avro_Avro Tools - Fatal编程技术网

Java 在avro文件中存储空值

Java 在avro文件中存储空值,java,avro,avro-tools,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@te

我有一些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
  }
我能够将lockedQuery空值添加到GenericRecord对象,而不会出现问题

GenericRecord record = new GenericData.Record(schema);
if(json.isNull("lockedQuery")){
    record.put("lockedQuery", null);
} 
然而,稍后当我试图将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
}
编辑:这是MyAvroRecord

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

为了能够将Avro字段设置为
null
,您应该在Avro模式中允许此操作,方法是将
null
添加为字段的可能类型之一。查看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
我也有这个问题,现在已经解决了

我在中找到了
@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;
}

有了
MyAvroRecord
的定义可能会有所帮助。我不是一个特别的Avro专家,但在Java中,通常不能将
null
存储在
boolean
(小写)字段中,因为它是一个原语。如果要在布尔值中存储空值,必须使用
布尔值
(大写),这是一个对象,可以为空。谢谢您的建议。我添加了MyAvroRecord中的成员定义。架构文件与类型匹配。我使用boolean并切换到boolean对象,但仍然有相同的空指针。当我将“false”存储为默认值时,错误会消失,但我仍然不能将null与基于对象的布尔值一起使用。如何在Java界面中不使用架构文件来完成此操作?您可以使用SchemaBuilder来完成此操作,方法是将字段的类型设置为
.type(SchemaBuilder.unionOf().nullType()和().stringType().endUnion())
import org.apache.avro.reflect.Nullable;

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