java - Spring 数据 Neo4j + Kotlin 上的日期转换器
问题描述
我正在为一个简单的项目从 Java 切换到 Kotlin,但我正在解决一个转换问题。我在数据库上:
CREATE (:Meeting {on: '2018-10-09', location: "Oracle's offices"})
在 kotlin 中(使用 SpringBoot + Spring Data neo4J)
@NodeEntity
data class Meeting(
@Id @GeneratedValue var id: Long?,
@DateString("yyyy-MM-dd") var on: LocalDate?,
var location: String?,
@Relationship(value = "ON") var topics: List<Topic> = ArrayList(),
@Relationship(value = "IN", direction = Relationship.INCOMING) var
participants: List<Person> = ArrayList(),
@Relationship(value = "ON") var event: Event?
) : Comparable<Meeting> {
override fun compareTo(other: Meeting): Int {
return this.on!!.compareTo(other.on)
}
}
但是当我执行一个简单的 meetingRepository.findAll() 时,我有那个异常
java.time.format.DateTimeParseException: Text '2018-10-09' could not be parsed at index 4
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) ~[na:1.8.0_171]
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) ~[na:1.8.0_171]
at java.time.LocalDate.parse(LocalDate.java:400) ~[na:1.8.0_171]
at org.springframework.format.datetime.standard.TemporalAccessorParser.parse(TemporalAccessorParser.java:69) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.format.datetime.standard.TemporalAccessorParser.parse(TemporalAccessorParser.java:46) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:200) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.data.neo4j.conversion.Neo4jOgmEntityInstantiatorAdapter$Neo4jPropertyValueProvider.getParameterValue(Neo4jOgmEntityInstantiatorAdapter.java:89) ~[spring-data-neo4j-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.data.convert.KotlinClassGeneratingEntityInstantiator$DefaultingKotlinClassInstantiatorAdapter.extractInvocationArguments(KotlinClassGeneratingEntityInstantiator.java:230) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.data.convert.KotlinClassGeneratingEntityInstantiator$DefaultingKotlinClassInstantiatorAdapter.createInstance(KotlinClassGeneratingEntityInstantiator.java:204) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.data.neo4j.conversion.Neo4jOgmEntityInstantiatorAdapter.createInstance(Neo4jOgmEntityInstantiatorAdapter.java:61) ~[spring-data-neo4j-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.neo4j.ogm.metadata.reflect.EntityFactory.instantiate(EntityFactory.java:126) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.metadata.reflect.EntityFactory.newObject(EntityFactory.java:95) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.context.GraphEntityMapper.mapNodes(GraphEntityMapper.java:237) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.context.GraphEntityMapper.mapEntities(GraphEntityMapper.java:212) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:138) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:94) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.session.delegates.LoadByTypeDelegate.lambda$loadAll$0(LoadByTypeDelegate.java:107) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.session.Neo4jSession.doInTransaction(Neo4jSession.java:574) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.session.Neo4jSession.doInTransaction(Neo4jSession.java:558) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.session.delegates.LoadByTypeDelegate.loadAll(LoadByTypeDelegate.java:94) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.session.delegates.LoadByTypeDelegate.loadAll(LoadByTypeDelegate.java:118) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at org.neo4j.ogm.session.Neo4jSession.loadAll(Neo4jSession.java:192) ~[neo4j-ogm-core-3.1.9.jar:3.1.9]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.lambda$invoke$0(SharedSessionCreator.java:108) ~[spring-data-neo4j-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.invokeInTransaction(SharedSessionCreator.java:139) ~[spring-data-neo4j-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.invoke(SharedSessionCreator.java:110) ~[spring-data-neo4j-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at com.sun.proxy.$Proxy101.loadAll(Unknown Source) ~[na:na]
at org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.findAll(SimpleNeo4jRepository.java:154) ~[spring-data-neo4j-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.findAll(SimpleNeo4jRepository.java:149) ~[spring-data-neo4j-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:99) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at com.sun.proxy.$Proxy105.findAll(Unknown Source) ~[na:na]
at be.namuco.dynanetwork.manager.InfoManager.getAllMeetings(InfoManager.kt:80) ~[classes/:na]
at be.namuco.dynanetwork.controller.InfoController.getAllMeetings(InfoController.kt:51) ~[classes/:na]
然后我尝试使用注释@Converter 和这样的自定义转换器
class LocalDateParser : AttributeConverter<LocalDate, String> {
val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
override fun toGraphProperty(value: LocalDate): String? {
return formatter.format(value)
}
override fun toEntityAttribute(value: String?): LocalDate {
return LocalDate.parse(value);
}
}
没有任何成功
- - - - - - - - - 编辑 - - - - - - - - - - - -
谢谢@Xavier
- - - - - - - - - 编辑 - - - - - - - - - - - -
当我使用调试器查看时,我可以看到解析器正在寻找一个模式
MM/dd/yy
有人能帮我吗 ?
配置:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-http-driver</artifactId>
<version>3.1.11</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-bolt-driver</artifactId>
<version>3.1.11</version>
</dependency>
解决方案
只需尝试将以下Formatter bean 添加到您的项目中:
@Component
class LocalDateFormatter : Formatter<LocalDate> {
override fun parse(text: String, locale: Locale): LocalDate {
return LocalDate.parse(text, DateTimeFormatter.ISO_LOCAL_DATE)
}
override fun print(obj: LocalDate, locale: Locale): String {
return DateTimeFormatter.ISO_LOCAL_DATE.format(obj)
}
}
更新
spring-boot-starter-web
如果您的项目中有依赖项,则上述代码有效。但如果你不这样做 - 你可以添加FormattingConversionServiceFactoryBean
到项目中并手动注册你的格式化程序(然后你可以从中删除@Component
注释):
@Bean
fun formattingConversionServiceFactoryBean(): FormattingConversionServiceFactoryBean {
val factoryBean = FormattingConversionServiceFactoryBean()
factoryBean.setFormatters(setOf(LocalDateFormatter()))
return factoryBean
}
推荐阅读
- github - 如何在不共享 URL 的情况下将来自 Github 的提交的 git diff 发送给其他人?
- sap-cloud-sdk - Jenkins 的代理配置不适用于 groovy 管道脚本?
- r - 是否有一种有效的策略来对客户数据进行模糊连接以识别 R 中的单个客户 ID?
- javascript - 单击按钮时如何显示我的定价表?
- java - 创建内部类的实例如何工作?
- jboss - 引起:org.jboss.modules.ModuleNotFoundException:org.quartz
- python - 如何避免重复数据
- django - 谷歌 django-allauth 配置
- javascript - 用matter.js预测轨迹线
- python - 匹配相似但写作风格不同的字符串