【问题标题】:Custom codecs read issue in Spring data cassandraSpring数据cassandra中的自定义编解码器读取问题
【发布时间】:2017-07-04 01:57:57
【问题描述】:

我的 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 列表中的即时编解码器。

有什么方法可以直接将时间戳转换为 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);
    }
}

【问题讨论】:

标签: java spring datastax-java-driver spring-data-cassandra


【解决方案1】:

搞定了。读取转换器需要在 Row->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);
    }
}

【讨论】:

    猜你喜欢
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多