【问题标题】:Custom Cassandra converter自定义 Cassandra 转换器
【发布时间】:2016-04-19 14:05:37
【问题描述】:

我已经开始寻找很好的解决方案,如何使用 Spring CassandraOperations 很好地持久化实体。问题开始是因为我的实体中的某些字段不受 cassandra 支持,例如乔达日期时间。

解决方法是在 java.util.Date 类型的同一实体中添加其他字段,而不是 joda DateTime,用 @Transient 标记不需要的字段。但这不干净,所以我开始寻找自动自定义转换。

目前 spring-data-cassandra 参考没有提供如何注册自定义转换器的信息。 http://docs.spring.io/spring-data/cassandra/docs/current/reference/html/#cassandra.custom-converters

是否可以在 CassandraSessionFactoryBean 中注册自定义转换器(如此处 Spring Data Cassandra LocalDateTime Conversion)?

这是我的代码 @配置 公共类 CassandraConfig {

@Value("${cassandra.contactpoints}")
private String cassandraContactPoint;

@Value("${cassandra.port}")
private int cassandraPort;

@Value("${cassandra.keyspace}")
private String cassandraKeySpace;

@Bean
public CassandraClusterFactoryBean cluster() {

    CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
    cluster.setContactPoints(cassandraContactPoint);
    cluster.setPort(cassandraPort);

    return cluster;
}

@Bean
public CassandraMappingContext mappingContext() {
    return new BasicCassandraMappingContext();
}

@Bean
public CassandraConverter converter() {
    return new MappingCassandraConverter(mappingContext());
}

@Bean
public CassandraSessionFactoryBean session() throws Exception {
    CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
    session.setCluster(cluster().getObject());
    session.setKeyspaceName(cassandraKeySpace);
    session.setConverter(converter());
    session.setSchemaAction(SchemaAction.NONE);

    return session;
}

@Bean
public CassandraOperations cassandraTemplate() throws Exception {
    return new CassandraTemplate(session().getObject());
}

@Bean
public ConversionService getConversionService() {
    ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
    bean.setConverters(new HashSet<>(getConverters()));
    bean.afterPropertiesSet();

    return bean.getObject();
}

private Set<Converter<?, ?>> getConverters() {
    Set<Converter<?, ?>> converters = new HashSet<>();
    converters.addAll(Jsr310Converters.getConvertersToRegister());
    converters.add(new DateTimeWriteConverter());
    converters.add(new DateTimeReadConverter());

    return converters;
}

public static class DateTimeWriteConverter implements Converter<DateTime, Long> {
    @Override
    public Long convert(DateTime source) {
        return source.getMillis();
    }
}

public static class DateTimeReadConverter implements Converter<Long, DateTime> {
    @Override
    public DateTime convert(Long source) {
        return new DateTime(source);
    }
}

}

【问题讨论】:

    标签: spring spring-data spring-data-cassandra


    【解决方案1】:

    Spring Cassandra 的自定义转换在您创建 CassandraCustomConversions bean 时起作用。只需添加您的自定义转换器,默认转换器将保留。下面是我的@Configuration 类。

    @Bean
    CassandraCustomConversions cassandraCustomConversions() {
        List<Converter<?, ?>> converters = new ArrayList<>();
        converters.add(new MyDataReadConverter());
        return new CassandraCustomConversions(converters);
    }
    
    static class CounterDataReadConverter implements Converter<ByteBuffer, MyData> {
        @Override
        public MyData convert(ByteBuffer source) {
            try {
                return MyData.parseFrom(source.array());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    我正在使用基于 SpringBoot 2.0.0.RELEASE 的 spring-boot-starter-data-cassandra。

    【讨论】:

    • 不知道cassandra 2.0是否增加了multikeyspace支持
    • @bill23 不知何故这似乎对我不起作用。仍然是错误没有找到能够从类型 [java.lang.String] 转换为类型 [com.narvar.orderpull.cassandra.model.APIConfiguration] 的转换器。我有一个弹簧启动模块,它具有与上面相同的类。另一个模块使用 Cassandra 模块。即使在配置您的解决方案时也会出错。
    猜你喜欢
    • 1970-01-01
    • 2013-04-12
    • 2012-03-15
    • 2021-01-28
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多