Spring Data cassandra中的自定义编解码器读取问题

r3i60tvu  于 2022-09-27  发布在  Spring
关注(0)|答案(1)|浏览(132)

我在Cassandra表中有一个时间戳字段,我想将其Map到JavaInstant类型。写作时很容易做到这一点。
我添加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读回时,读取时间戳被Map到Date,我无法改变这种行为。因此,我需要向实体添加一个特殊的构造函数,以便将Date转换为Instant。
我的分析。在分析Row数据时,Cassandra执行查找以查找合适的编解码器。它不考虑所提供实体构造函数的参数类型,只拾取第一个可以处理行数据的编解码器。在我的例子中,它选择timestamp->date编解码器,因为它出现在CodecRegistry编解码器列表中的timestamp->即时编解码器之前。
有没有办法直接将时间戳转换为即时?
编辑
尝试注册读写转换器,但读转换器未被使用。

@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);
    }
}
gudnpqoy

gudnpqoy1#

让它工作起来。读取转换器需要位于行->类级别。

@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);
    }
}

相关问题