web-dev-qa-db-fra.com

Stockage de valeurs nulles dans des fichiers avro

J'ai quelques données json qui ressemblent à ceci:

  {
    "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
  }

Je suis en mesure d'ajouter la valeur null verrouillé à un objet GenericRecord sans problème.

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

Cependant, plus tard, lorsque j'essaie d'écrire cet objet GenericRecord dans un fichier avro, j'obtiens une exception de pointeur nul.

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
}

Lorsque j'exécute ce code, j'obtiens l'exception suivante. Tous les conseils sur la façon de traiter une valeur nulle dans un fichier Avro sont très appréciés. Merci d'avance.

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)

EDIT: voici le MyAvroRecord

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

Pour pouvoir définir le champ Avro sur null, vous devez l'autoriser dans le schéma Avro, en ajoutant null comme l'un des types possibles du champ. Jetez un œil à l'exemple de la documentation Avro:

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

ici userName est déclaré comme type composite qui pourrait être null ou string. Ce type de définition permet de mettre le champ userName à null. Comme le contraste userId ne peut contenir que des valeurs longues, donc essayer de définir userId sur null entraînera NullPointerException.

17
Vladimir Kroz

J'ai aussi ce problème et maintenant je l'ai résolu.

J'ai trouvé @Nullable annotation dans Apache Avro pour déclarer que le champ est nullable.

Donc, dans cet exemple, nous devrions

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