2017-02-15 1 views
0

Ich habe ein Timestamp-Feld in meiner Cassandra-Tabelle, die ich auf einen Java Instant Typ zuordnen möchte. Es ist ziemlich einfach, dies beim Schreiben zu erreichen.Benutzerdefinierte Codecs lesen Problem in Spring-Daten cassandra

Ich füge die custom codecs hinzu.

Sagen Sie Spring, um meinen Instant zu einem anderen Typ nicht zu konvertieren.

private enum InstantWriteConverter implements Converter<Instant, Instant> { 
    INSTANT; 

    @Override 
    public Instant convert(Instant source) { 
     return source; 
    } 
} 

Auf diese Weise wird Instant so weitergegeben wie es ist und wird vom InstantCodec verarbeitet.

Beim Zurücklesen von Cassandra wird der gelesene Zeitstempel jedoch auf Date gemappt und ich kann dieses Verhalten nicht ändern. Aus diesem Grund muss ich meiner Entität einen speziellen Konstruktor hinzufügen, um das Datum in Instant zu konvertieren.

Meine Analyse. Beim Analysieren der Row-Daten, Cassandra performs a look bis zu einem geeigneten Codec finden. Es berücksichtigt nicht die Parametertypen des bereitgestellten Entitätskonstruktors und nimmt einfach den ersten Codec auf, der die Zeilendaten verarbeiten kann. In meinem Fall greift es auf den timestamp-> date codec zurück, weil sein vor dem timestamp vorhandener Code in der CodecRegistry codecs Liste steht.

Sie können den Zeitstempel direkt in Instant konvertieren?

EDIT

Wandler Schreib lesen versucht, die Registrierung, aber der Lesewandler nicht verwendet zu werden.

@WritingConverter 
private enum InstantWriteConverter implements Converter<Instant, Long> { 
    INSTANT; 

    @Override 
    public Long convert(Instant source) { 
     return source.toEpochMilli(); 
    } 
} 

@ReadingConverter 
private enum InstantReadConverter implements Converter<Long, Instant> { 
    INSTANT; 

    @Override 
    public Instant convert(Long source) { 
     return Instant.ofEpochMilli(source); 
    } 
} 
+0

Sie können einen benutzerdefinierten Konverter Tupel registrieren (Lese- und Schreib-Wandler) 'Instant' zu lesen (siehe http://docs.spring.io/spring-data/cassandra/docs/current/reference/html/ # cassandra.custom-converters) – mp911de

+0

Während des Lesevorgangs werden die Konverter nicht verwendet, Instant wird jedoch in java.util.Date konvertiert. – Dexter

Antwort

0

Es funktioniert. Der Lese-Konverter muss auf Row-> Class level sein.

@Override 
    protected ClusterBuilderConfigurer getClusterBuilderConfigurer() { 
     return clusterBuilder -> { 

      clusterBuilder.getConfiguration().getCodecRegistry() 
          .register(InstantCodec.instance, 
            LocalDateCodec.instance, 
            LocalTimeCodec.instance); 
      return clusterBuilder; 
     }; 
    } 

    @Override 
    public CustomConversions customConversions() { 
     return new CustomConversions(
       Arrays.asList(ReadConverter.INSTANCE, 
           InstantWriteConverter.INSTANCE, 
           LocalTimeWriteConverter.INSTANCE, 
           DurationWriteConverter.INSTANCE, 
           LocalDateWriteConverter.INSTANCE)); 
    } 

@ReadingConverter 
private enum ReadConverter implements Converter<Row, FlightFareInfo> { 
    INSTANCE; 

    @Override 
    public FlightFareInfo convert(Row source) { 

     return FlightFareInfo.convertFromRow(source); 
    } 
}