Sto cercando un modo per convertire un POJO in un oggetto avro in un modo generico. L'implementazione dovrebbe essere solida per qualsiasi modifica della classe POJO. L'ho raggiunto ma riempiendo esplicitamente il record avro (vedi esempio sotto).Conversione generica da POJO a Avro Record
C'è un modo per sbarazzarsi dei nomi dei campi codificati e basta riempire il disco avro dall'oggetto? La riflessione è l'unico modo, o avro fornisce questa funzionalità fuori dalla scatola?
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);
}
}
Perché non utilizzare [di Avro ReflectDatumWriter] (http: // StackOverflow .com/questions/11866466/using-apache-avro-reflect) per serializzare il POJO? –
Sto usando avro in contesto hadoop. Per la serializzazione vorrei utilizzare AvroParquetOutputFormat – fab
Un approccio inefficiente avrebbe [ReflectDatumWriter scrivere un POJO in byte, quindi GenericDatumReader leggerà i byte in GenericRecord] (http://stackoverflow.com/questions/26435299/write-pojos-to-parquet -file-con-riflessione). –