Spring数据Cassandra LocalDateTime转换 [英] Spring Data Cassandra LocalDateTime Conversion

查看:371
本文介绍了Spring数据Cassandra LocalDateTime转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开展一个项目,我们有一个实体,我们想要持有一个类型为LocalDateTime的领域,我们知道cassandra没有这种类型转换的本机支持,我们使用Spring的支持创建了自己的定制转换器对于转换器,但是似乎Spring-Data-Cassandra无法识别它们,或者理解该字段应该映射到列。



这是我们如何使用Spring的转换服务注册转换器。

 < bean id =conversionServiceclass =org.springframework.context.support.ConversionServiceFactoryBean> 
< property name =conversions>
< set>
<! - 转换器列表 - >
< bean class =com.klappo.userservice.api.persistence.converters.DateToLocalDateTimeConverter/>
< bean class =com.klappo.userservice.api.persistence.converters.LocalDateTimeToDateConverter/>
< bean class =com.klappo.userservice.api.persistence.converters.DateToLocalDateConverter/>
< bean class =com.klappo.userservice.api.persistence.converters.LocalDateToDateConverter/>
< / set>
< / property>
< / bean>

最终结果是在我们的应用程序启动时抛出以下异常:

 导致:
org.springframework.data.cassandra.mapping.VerifierMappingExceptions:java.time.LocalDate:| Cassandra实体必须有@Table ,@Persistent或@PrimaryKeyClass注释
在org.springframework.data.cassandra.mapping.BasicCassandraPersistentEntityMetadataVerifier.verify(BasicCassandraPersistentEntityMetadataVerifier.java:45)
在org.springframework.data.cassandra.mapping.BasicCassandraPersistentEntity.verify(BasicCassandraPersistentEntity.java:198)
在org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:297)
在org.springframework.data.mapping.context.AbstractMappingContext $ PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java: 469)
在org.springframework.data.mapping.context.AbstractMappingContext $ PersistentPropertyCreator.doWith(AbstractMappingContext.java:426)
在org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:607)
在org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:294)
在org.springframework.data.mapping.con text.AbstractMappingContext $ PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:469)
在org.springframework.data.mapping.context.AbstractMappingContext $ PersistentPropertyCreator.doWith(AbstractMappingContext.java:426)
在org.springframework。 util.ReflectionUtils.doWithFields(ReflectionUtils.java:607)
在org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:294)
在org.springframework.data.mapping。 context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:256)
在org.springframework.data.mapping.context.AbstractMappingContext.initialize(AbstractMappingContext.java:372)
在org.springframework.data.cassandra。 mapping.BasicCassandraMappingContext.initialize(BasicCassandraMappingContext.java:79)
在org.springframework.data.mapping.context.AbstractMappingContext.afterPropertiesSet(AbstractMappingContext.java:362)
在或g.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
在org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:302)
在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
在org.springframework.beans.factory.support。 AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
在org.springframework.beans.factory.support。 BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
在org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:632)
在org.springframework.beans.factory.support。 ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1114)
在org.springframework.beans.factory.support。 AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1017)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreat eBean(AbstractAutowireCapableBeanFactory.java:504)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
在org.springframework.beans.factory.support.AbstractBeanFactory $ 1 .getObject(AbstractBeanFactory.java:302)
在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
在org.springframework.beans.factory.support.AbstractBeanFactory .doGetBean(AbstractBeanFactory.java:298)
在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
在org.springframework.beans.factory.support.BeanDefinitionValueResolver .resolveReference(BeanDefinitionValueResolver.java:328)
在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
在org.springframework.beans.factory。支持.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
在org.springframework.beans.factory。支持.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
在org.springframework.beans.factory。 support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:302)
在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
在org.springframework.beans.factory .support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(Abst ractBeanFactory.java:193)
在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary( BeanDefinitionValueResolver.java:108)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean( AbstractAutowireCapableBeanFactory.java:1197)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean( AbstractAutowireCapableBeanFactory.java:475)
在org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBean Factory.java:302)
在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean( AbstractBeanFactory.java:298)
在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference( BeanDefinitionValueResolver.java:328)
在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues( AbstractAutowireCapableBeanFactory.java:1456)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
在org.springframework.beans .factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
在org.springframework.beans .factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:302)
在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
在org.springframework。 bean.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
在org.springframework。 beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
在org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactor y.java:960)
在org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement。注入(AutowiredAnnotationBeanPostProcessor.java:480)
在org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor。 postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory。 doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAut owireCapableBeanFactory.java:475)
在org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:302)
在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:228)
在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
在org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:193)
在org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
在org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext .java:760)
在org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
在org.springframework.web.context.ContextLoader.configureAndRefreshWebAp plicationContext(ContextLoader.java:403)
在org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
在org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener。 java:106)
在org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:800)
在org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java: 444)
在org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:791)
在org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:294)
在org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349)
在org.eclipse.jetty.maven.plugin.JettyWebAppContext.startWebapp(JettyWebAppContext.java:296)
在org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342)
在org.eclipse.jett y.server.handler.ContextHandler.doStart(ContextHandler.java:741)
在org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505)
在org.eclipse.jetty。 maven.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:365)
在org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
在org.eclipse.jetty。 util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
在org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
在org.eclipse.jetty。 server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
在org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:163)
在org.eclipse.jetty。 util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
在org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
在org.eclipse.jetty。 util.component.ContainerL ifeCycle.doStart(ContainerLifeCycle.java:114)
在org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
在org.eclipse.jetty.util.component。 AbstractLifeCycle.start(AbstractLifeCycle.java:68)
在org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
在org.eclipse.jetty.server.Server。 start(Server.java:387)
在org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
在org.eclipse.jetty.server.handler.AbstractHandler。 doStart(AbstractHandler.java:61)
在org.eclipse.jetty.server.Server.doStart(Server.java:354)
在org.eclipse.jetty.maven.plugin.JettyServer.doStart( JettyServer.java:73)
在org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
在org.eclipse.jetty.maven.plugin.AbstractJettyMojo.startJetty( AbstractJettyMojo.java:534)
在org.eclipse.jetty.maven.plugin.AbstractJet tyMojo.execute(AbstractJettyMojo.java:357)
在org.eclipse.jetty.maven.plugin.JettyRunMojo.execute(JettyRunMojo.java:167)
在org.apache.maven.plugin.DefaultBuildPluginManager。 executeMojo(DefaultBuildPluginManager.java:132)
在org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
在org.apache.maven.lifecycle.internal.MojoExecutor。执行(MojoExecutor.java:153)
在org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
在org.apache.maven.lifecycle.internal.LifecycleModuleBuilder。 buildProject(LifecycleModuleBuilder.java:116)
在org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
在org.apache.maven.lifecycle.internal.builder。 singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
在org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)
在org.apach e.maven.DefaultMaven.doExecute(DefaultMaven.java:347)
在org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154)
在org.apache.maven.cli.MavenCli。执行(MavenCli.java:582)
在org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
在org.apache.maven.cli.MavenCli.main(MavenCli。 java:158)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl。调用(DelegatingMethodMethodAccessorImpl.java:43)
在java.lang.reflect.Method.invoke(Method.java:483)
在org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(启动器。 java:289)
在org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
在org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(启动器。 java:415)
在org.codehaus.plexus.classworlds.launcher.Launcher.main( Launcher.java:356)
在org.codehaus.classworlds.Launcher.main(Launcher.java:46)

Spring的数据文档缺少相当多的,所以我们想知道是否有人尝试使用spring-data-cassandra的定制类型转换器,如果是,我们想知道什么是正确的



提前感谢

解决方案

不幸的是春天数据卡桑德拉< = 1.2.x可以仅用于可以直接映射到此列表中的数据类型的bean:
http://www.datastax.com/documentation/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html



我遇到同样的问题,因为想把我的类映射到Cassandra中的TEXT字段,但是无法做到这一点。经过几天的尝试,我得出的结论是,不可能在Spring-Data for Cassandra中使用自定义类型转换器(使用版本1.2.0.M1进行测试)。



CassandraTemplate使用嵌入了DefaultConversionService的MappingCassandraConverter,但是在Spring-data-cassandra模块中的任何地方都不使用该DefaultConversionService。它仅用于与SpringData API集成。



您可以在图书馆的代码中找到convertService仅在

  BeanWrapper< S> wrapper = BeanWrapper.create(instance,conversionService); 

只需跳过conversionService:

  @Deprecated 
public static< T> BeanWrapper< T> create(T bean,ConversionService conversionService){
返回新的BeanWrapper< T>(bean);
}

您可以在使用ColumnReader的MappingCassandraConverter.readPropertyFromRow(...)中看到。 get(int i)只支持Cassandra的MAP,LIST,SET和主数据类型(Text,Numbers,UUID,java.util.Date,Boolean,ByteBuffer)。



另外BasicCassandraMappingContext.verifier(BasicCassandraPersistentEntityMetadataVerifier)抛出异常尝试写入任何不能映射到支持的Cassandra类型的字段或不是@Table。



这就是为什么你有例外

  //尝试检查LocalDateTime中的嵌入字段'date'的转换
org.springframework.data.cassandra.mapping.VerifierMappingExceptions:java.time.LocalDate

所以唯一的方法解决它是根据您的需要在spring-data-cassandra之上使用ConversionService。



转换服务部分的示例代码:

  import org.springframework.data.convert.Jsr310Converters; 

...

@Bean
public ConversionService getConversionService(){
//创建DefaultConversionService
ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean() ;
bean.setConverters(new HashSet(getConverters()));
Bean.afterPropertiesSet();
ConversionService service = bean.getObject();
退货服务;
}

私人设置<转换器<?,?>> getConverters(){
设置<转换器<?,?>>转换器=新的HashSet<转换器<?,?>>();
converters.addAll(Jsr310Converters.getConvertersToRegister());
converters.add(new TimeWriteConverter());
converters.add(new TimeReadConverter());

返回转换器;
}

public static class TimeWriteConverter实现Converter< LocalDateTime,Long> {
@Override
public Long convert(LocalDateTime source){
return source.atZone(ZoneId.systemDefault())。toInstant()。toEpochMilli();
}
}
public static class TimeReadConverter实现Converter< Long,LocalDateTime> {
@Override
public LocalDateTime convert(Long source){
return LocalDateTime.ofInstant(Instant.ofEpochMilli(source),ZoneId.systemDefault());
}
}


I'm working on a project where we have an entity we want to persist with a field of type LocalDateTime, we know cassandra does not have native support for this type conversion, we've created our own custom converter using Spring's support for converters, however it seems Spring-Data-Cassandra is unable to either recognise them or understand that the field should be mapped to a column.

This is how we've registered our converters with Spring's conversion service.

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <!-- list of converters-->
                <bean class="com.klappo.userservice.api.persistence.converters.DateToLocalDateTimeConverter" />
                <bean class="com.klappo.userservice.api.persistence.converters.LocalDateTimeToDateConverter" />
                <bean class="com.klappo.userservice.api.persistence.converters.DateToLocalDateConverter" />
                <bean class="com.klappo.userservice.api.persistence.converters.LocalDateToDateConverter" />
            </set>
        </property>
    </bean>

The end result is the following exception thrown on startup of our application:

    Caused by: 
org.springframework.data.cassandra.mapping.VerifierMappingExceptions: java.time.LocalDate:|Cassandra entities must have the @Table, @Persistent or @PrimaryKeyClass Annotation|
    at org.springframework.data.cassandra.mapping.BasicCassandraPersistentEntityMetadataVerifier.verify(BasicCassandraPersistentEntityMetadataVerifier.java:45)
    at org.springframework.data.cassandra.mapping.BasicCassandraPersistentEntity.verify(BasicCassandraPersistentEntity.java:198)
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:297)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:469)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:426)
    at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:607)
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:294)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:469)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:426)
    at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:607)
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:294)
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:256)
    at org.springframework.data.mapping.context.AbstractMappingContext.initialize(AbstractMappingContext.java:372)
    at org.springframework.data.cassandra.mapping.BasicCassandraMappingContext.initialize(BasicCassandraMappingContext.java:79)
    at org.springframework.data.mapping.context.AbstractMappingContext.afterPropertiesSet(AbstractMappingContext.java:362)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:632)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1114)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1017)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:800)
    at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:444)
    at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:791)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:294)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349)
    at org.eclipse.jetty.maven.plugin.JettyWebAppContext.startWebapp(JettyWebAppContext.java:296)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505)
    at org.eclipse.jetty.maven.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:365)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:163)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:387)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:354)
    at org.eclipse.jetty.maven.plugin.JettyServer.doStart(JettyServer.java:73)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:534)
    at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:357)
    at org.eclipse.jetty.maven.plugin.JettyRunMojo.execute(JettyRunMojo.java:167)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:46)

Spring's data documentation on this is lacking quite a bit, so we're wondering if anyone has attempted to use custom type converters with spring-data-cassandra and if so, we'd like to know what's the right way of doing it.

Thanks in advance.

解决方案

Unfortunatey the spring-data-cassandra ver. <= 1.2.x could be used only with beans which could be directly mapped to datatypes from this list: http://www.datastax.com/documentation/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html

I met the same problem, because wanted to map my classes into TEXT fields in Cassandra, but couldn't do it. After several days of trying I came to the conclusion that it is not possible to use custom type converters in Spring-Data for Cassandra (tested with version 1.2.0.M1).

CassandraTemplate uses MappingCassandraConverter which has embedded DefaultConversionService, but this DefaultConversionService is not used anywhere in the spring-data-cassandra module. It was introduced only for integration with SpringData API.

You could find in the code of library that conversionService is using only in

BeanWrapper<S> wrapper = BeanWrapper.create(instance, conversionService);

which just skips conversionService:

@Deprecated
public static <T> BeanWrapper<T> create(T bean, ConversionService conversionService) {
    return new BeanWrapper<T>(bean);
}

You could see in MappingCassandraConverter.readPropertyFromRow(...) which uses ColumnReader.get(int i) where supported only Cassandra's MAP, LIST, SET and primary data types (Text, Numbers, UUID, java.util.Date, Boolean, ByteBuffer).

In addition BasicCassandraMappingContext.verifier (BasicCassandraPersistentEntityMetadataVerifier) throw exception on attempt to write any field which could not be mapped to supported types of Cassandra or is not @Table.

That's why you had the the exception

// it was attempt to check conversion of an embedded field 'date' in LocalDateTime    
org.springframework.data.cassandra.mapping.VerifierMappingExceptions: java.time.LocalDate

So the only way to solve it is using ConversionService on top of spring-data-cassandra for your needs.

Sample code for conversion service part:

import org.springframework.data.convert.Jsr310Converters;

...    

@Bean
public ConversionService getConversionService() {
    // creates DefaultConversionService
    ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
    bean.setConverters(new HashSet<>(getConverters()));
    bean.afterPropertiesSet();
    ConversionService service = bean.getObject();
    return service;
}

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

    return converters;
}

public static class TimeWriteConverter implements Converter<LocalDateTime, Long> {
    @Override
    public Long convert(LocalDateTime source) {
        return source.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }
}
public static class TimeReadConverter implements Converter<Long, LocalDateTime> {
    @Override
    public LocalDateTime convert(Long source) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(source), ZoneId.systemDefault());
    }
}

这篇关于Spring数据Cassandra LocalDateTime转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆