Spring Data MongoDB与Java 8 LocalDate映射异常

11

我尝试使用Java 8日期时间API中的LocalTime与Spring Data MongoDB一起使用。插入文档按预期工作,但当我尝试读取文档时,我遇到了以下错误:

Exception in thread "main" java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:637)
    ....
Caused by: org.springframework.data.mapping.model.MappingException: No property null found on entity class java.time.LocalDate to bind constructor parameter to!
    at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:74)
    at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:63)
    at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:71)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:257)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:237)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1109)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access$100(MappingMongoConverter.java:78)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1058)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getValueInternal(MappingMongoConverter.java:789)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:270)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:263)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:261)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:263)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:237)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:201)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:197)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:78)
    at org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:2005)
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1699)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1522)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1506)
    at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:532)
    at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:217)
    at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:174)
    at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:44)
    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.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:358)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:343)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy28.findAll(Unknown Source)
    at hello.Application.run(Application.java:36)
    at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:634)
    ... 5 more

我尝试使用Spring网站上的示例:http://spring.io/guides/gs/accessing-data-mongodb/,我只是将Customer更改为具有出生日期:

package hello;

import org.springframework.data.annotation.Id;
import java.time.LocalDate;

public class Customer {

    @Id
    private String id;

    private String firstName;
    private String lastName;
    private LocalDate birthDay;

    public Customer() {}

    public Customer(String firstName, String lastName, LocalDate birthDay) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.birthDay = birthDay;
    }

    @Override
    public String toString() {
        return String.format(
                "Customer[id=%s, firstName='%s', lastName='%s']",
                id, firstName, lastName);
    }

}
3个回答

9
我为这四种转换选项编写了一小段代码:
  • DateToLocalDateTimeConverter
  • DateToLocalDateConverter
  • LocalDateTimeToDateConverter
  • LocalDateToDateConverter

以下是一个示例:

public class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {

    @Override 
    public LocalDateTime convert(Date source) { 
        return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault()); 
    }
}

所有示例在此处

然后,通过在mongodb连接的xml配置中包含此内容,我能够使用java 8日期处理mongodb(记得添加所有转换器):

<mongo:mapping-converter>
    <mongo:custom-converters>
        <mongo:converter>
            <bean class="package.DateToLocalDateTimeConverter" />
        </mongo:converter>
    </mongo:custom-converters>
</mongo:mapping-converter>

好的!在即将发布的1.7 M1中将有一个开箱即用的实现。 - Oliver Drotbohm
1
@OliverGierke 我尝试使用http://repo.spring.io/libs-milestone/org/springframework/data/spring-data-mongodb/1.7.0.M1/,但仍然出现“在实体类java.time.LocalDateTime上找不到属性null以绑定构造函数参数”的错误。 - Eduard Grinchenko
我仍然面临这个问题.. 除了定义自己的自定义转换器之外,还有其他帮助吗? - Mehraj Malik

3

1
目前不支持此功能,主要原因是MongoDB目前不支持存储Java 8日期时间类型。建议将内部属性转换为传统的Date类型,并在域类的API上进行转换(就像使用Hibernate和JodaTime一样)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接