Ich bin auf der Suche nach einer Möglichkeit, ein POJO in ein generisches avro-Objekt zu konvertieren. Die Implementierung sollte robust gegenüber allen Änderungen der POJO-Klasse sein. Ich habe es erreicht, aber den avro-Datensatz explizit gefüllt (siehe Beispiel unten).Generische Konvertierung von POJO zu Avro Record
Gibt es eine Möglichkeit, die fest codierten Feldnamen loszuwerden und nur den Avro-Datensatz aus dem Objekt zu füllen? Ist Reflektion der einzige Weg, oder bietet avro diese Funktionalität sofort an?
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData.Record;
import org.apache.avro.reflect.ReflectData;
public class PojoToAvroExample {
static class PojoParent {
public final Map<String, String> aMap = new HashMap<String, String>();
public final Map<String, Integer> anotherMap = new HashMap<String, Integer>();
}
static class Pojo extends PojoParent {
public String uid;
public Date eventTime;
}
static Pojo createPojo() {
Pojo foo = new Pojo();
foo.uid = "123";
foo.eventTime = new Date();
foo.aMap.put("key", "val");
foo.anotherMap.put("key", 42);
return foo;
}
public static void main(String[] args) {
// extract the avro schema corresponding to Pojo class
Schema schema = ReflectData.get().getSchema(Pojo.class);
System.out.println("extracted avro schema: " + schema);
// create avro record corresponding to schema
Record avroRecord = new Record(schema);
System.out.println("corresponding empty avro record: " + avroRecord);
Pojo foo = createPojo();
// TODO: to be replaced by generic variant:
// something like avroRecord.importValuesFrom(foo);
avroRecord.put("uid", foo.uid);
avroRecord.put("eventTime", foo.eventTime);
avroRecord.put("aMap", foo.aMap);
avroRecord.put("anotherMap", foo.anotherMap);
System.out.println("expected avro record: " + avroRecord);
}
}
Warum nicht verwenden [Avro des ReflectDatumWriter] (http: // Stackoverflow .com/questions/11866466/using-apache-avro-reflect) um das POJO zu serialisieren? –
Ich benutze Avro im Hadoop-Kontext. Für Serialisierung würde ich gerne das AvroParquetOutputFormat verwenden – fab
Ein ineffizienter Ansatz hätte [ReflectDatumWriter schreiben ein POJO in Bytes dann GenericDatumReader liest die Bytes zu GenericRecord] (http://stackoverflow.com/questions/26435299/write-pojos-to-parquet -file-using-reflection). –