2012-11-06 11 views
8

In realtà sto tentando di serializzare oggetti contenenti date con Avro e la data deserializzata non corrisponde al valore previsto (testata con avro 1.7.2 e 1.7.1). Ecco la classe che sto serializzazione:Come serializzare una data utilizzando AVRO in Java

import java.text.SimpleDateFormat; 
import java.util.Date; 

public class Dummy { 
    private Date date; 
    private SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss.SSS"); 

    public Dummy() { 
    } 

    public void setDate(Date date) { 
     this.date = date; 
    } 

    public Date getDate() { 
     return date; 
    } 

    @Override 
    public String toString() { 
     return df.format(date); 
    } 
} 

Il codice utilizzato per serializzare/deserializzare:

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.util.Date; 

import org.apache.avro.Schema; 
import org.apache.avro.io.DatumReader; 
import org.apache.avro.io.DatumWriter; 
import org.apache.avro.io.Decoder; 
import org.apache.avro.io.DecoderFactory; 
import org.apache.avro.io.Encoder; 
import org.apache.avro.io.EncoderFactory; 
import org.apache.avro.reflect.ReflectData; 
import org.apache.avro.reflect.ReflectDatumReader; 
import org.apache.avro.reflect.ReflectDatumWriter; 

public class AvroSerialization { 

    public static void main(String[] args) { 
     Dummy expected = new Dummy(); 
     expected.setDate(new Date()); 
     System.out.println("EXPECTED: " + expected); 
     Schema schema = ReflectData.get().getSchema(Dummy.class); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     Encoder encoder = EncoderFactory.get().binaryEncoder(baos, null); 
     DatumWriter<Dummy> writer = new ReflectDatumWriter<Dummy>(schema); 
     try { 
      writer.write(expected, encoder); 
      encoder.flush(); 
      Decoder decoder = DecoderFactory.get().binaryDecoder(baos.toByteArray(), null); 
      DatumReader<Dummy> reader = new ReflectDatumReader<Dummy>(schema); 
      Dummy actual = reader.read(null, decoder); 
      System.out.println("ACTUAL: " + actual); 
     } catch (IOException e) { 
      System.err.println("IOException: " + e.getMessage()); 
     } 
    } 
} 

E l'output:

EXPECTED: 06/11/2012 05:43:29.188 
ACTUAL: 06/11/2012 05:43:29.387 

È legato ad un bug noto, o è legato al modo in cui sto serializzando l'oggetto?

+1

So che non sto rispondendo alla tua domanda, ma io * non * userei un SimpleDateFormat statico. Non è una classe thread-safe e di conseguenza fornirà risultati inaffidabili in un ambiente con thread –

+0

Grazie per il commento, questo non è in realtà un codice di produzione, ma solo una classe di test che ho sviluppato per esporre il mio problema. Ad ogni modo hai ragione, quindi ho rimosso il modificatore statico;) –

risposta

6

Penso che AVRO non serializzi la data a questo punto. Quello che vorrei fare è avvolgerlo in un'altra classe e archiviarlo a lungo (date.gettime()) mentre avro folks aggiungi this feature. E il motivo per cui si visualizzano valori di Data diversi è che ogni volta che (e avro) si crea un oggetto Date, esso inizializza la Data con l'ora di Sistema corrente.

+0

Grazie mille, sembra che Data non sia effettivamente supportata come indicato nella tua risposta e che la Data sia effettivamente inizializzata con l'ora corrente del Sistema. –

7

Avro 1.8 ora ha una data "logicalType", che annota int. Per esempio:

{ "name": "data", "type": "int", "logicalType": "data"}

Citando la specifica: "Un tipo logico data annota un int Avro, dove int memorizza il numero di giorni dall'epoca unix, 1 gennaio 1970 (calendario ISO). "

Problemi correlati