Java 在avro文件中存储空值
我有一些json数据如下所示: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
{
"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;
}