我的Cassandra表中有一个时间戳字段,我希望将其映射到Java Instant类型。 写作时很容易做到这一点。
我添加custom codecs。
@Override
protected ClusterBuilderConfigurer getClusterBuilderConfigurer() {
return clusterBuilder -> {
clusterBuilder.getConfiguration().getCodecRegistry()
.register(InstantCodec.instance,
LocalDateCodec.instance,
LocalTimeCodec.instance);
return clusterBuilder;
};
}
告诉spring不要将我的Instant转换为其他类型。
private enum InstantWriteConverter implements Converter<Instant, Instant> {
INSTANT;
@Override
public Instant convert(Instant source) {
return source;
}
}
这样,Instant就会按原样传递并由InstantCodec处理。
但是当从Cassandra读回来时,读取的时间戳被映射到Date,我无法改变这种行为。因此,我需要为我的实体添加一个特殊的构造函数,只是为了将Date转换为Instant。
我的分析。 在解析Row数据时,Cassandra performs a look最多可以找到合适的Codec。它不尊重所提供的实体构造函数的参数类型,只是选择可以处理行数据的第一个编解码器。在我的情况下,它会选择时间戳 - >日期编解码器,因为它存在于CodecRegistry codecs列表中的时间戳 - &gt;即时编解码器之前。
如何直接将时间戳转换为Instant?
修改
尝试注册读写转换器,但读取转换器未被使用。
@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 :(得分:0)
搞定了。读转换器需要在Row-&gt; Class级别。
@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);
}
}