Hibernate org.springframework.dao.InvalidDataAccessApiUsageException:参数值与预期的类型java.time.LocalDateTime不匹配
我刚开始处理别人开发的代码。它是基于规范模式使用Spring数据和Hibernate设计的 简而言之,如果我尝试使用字符串、布尔值或整数字段进行搜索,它将正常工作。例如,当我使用state==SP搜索/过滤时,我得到了结果,我可以看到硅藻土字段被正确填充。在这种情况下,hibernate不会抱怨无效数据: 使用“state==SP”成功搜索时从控制台复制 ... 跟踪2450---[nio-9000-exec-2]o.h.type.descriptor.sql.BasicExtractor:提取值([created17_12_]:[TIMESTAMP])-[2013-07-12T06:53:47] ... 然而,当我使用datetime搜索/筛选时,我得到了这个问题中总结的错误。例如:我搜索“createdDate==2014-06-03T18:48:33”,得到:Hibernate org.springframework.dao.InvalidDataAccessApiUsageException:参数值与预期的类型java.time.LocalDateTime不匹配,hibernate,datetime,spring-data,spring-data-jpa,jsonserializer,Hibernate,Datetime,Spring Data,Spring Data Jpa,Jsonserializer,我刚开始处理别人开发的代码。它是基于规范模式使用Spring数据和Hibernate设计的 简而言之,如果我尝试使用字符串、布尔值或整数字段进行搜索,它将正常工作。例如,当我使用state==SP搜索/过滤时,我得到了结果,我可以看到硅藻土字段被正确填充。在这种情况下,hibernate不会抱怨无效数据: 使用“state==SP”成功搜索时从控制台复制 ... 跟踪2450---[nio-9000-exec-2]o.h.type.descriptor.sql.BasicExtractor:提取
2018-03-23 17:38:17.547 ERROR 2450 --- [nio-9000-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [2014-06-03T18:48:33] did not match expected type [java.time.LocalDateTime (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [2014-06-03T18:48:33] did not match expected type [java.time.LocalDateTime (n/a)]] with root cause
java.lang.IllegalArgumentException: Parameter value [2014-06-03T18:48:33] did not match expected type [java.time.LocalDateTime (n/a)]
at org.hibernate.jpa.spi.BaseQueryImpl.validateBinding(BaseQueryImpl.java:897) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.internal.QueryImpl.access$000(QueryImpl.java:61) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.internal.QueryImpl$ParameterRegistrationImpl.bindValue(QueryImpl.java:235) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:638) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:163) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:32) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.criteria.compile.CriteriaCompiler$1$1.bind(CriteriaCompiler.java:109) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.criteria.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:366) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.criteria.compile.CriteriaCompiler.compile(CriteriaCompiler.java:130) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:699) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at sun.reflect.GeneratedMethodAccessor93.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347) ~[spring-orm-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at com.sun.proxy.$Proxy115.createQuery(Unknown Source) ~[na:na]
at sun.reflect.GeneratedMethodAccessor93.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) ~[spring-orm-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at com.sun.proxy.$Proxy115.createQuery(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:656) ~[spring-data-jpa-1.11.6.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:608) ~[spring-data-jpa-1.11.6.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:407) ~[spring-data-jpa-1.11.6.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_162]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:504) ~[spring-data-commons-1.13.6.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:489) ~[spring-data-commons-1.13.6.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461) ~[spring-data-commons-1.13.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56) ~[spring-data-commons-1.13.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) ~[spring-data-jpa-1.11.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) ~[spring-data-commons-1.13.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at com.sun.proxy.$Proxy150.findAll(Unknown Source) ~[na:na]
at br.com.moving.service.ApiServiceImpl.list(ApiServiceImpl.java:48)
调用findAll时存储库引发错误:
@Repository
@Transactional
public class ApiServiceImpl implements ApiService {
@PersistenceContext
private EntityManager em;
@Override
public <T> Page<T> list(Class<T> clazz, Class<? extends JpaSpecificationExecutor<T>> clazz2, String search,
Pageable pageable, Class<? extends Specification<T>> specClazz) {
JpaSpecificationExecutor<T> repository = new JpaRepositoryFactory(em).getRepository(clazz2);
SpecificationBuilder<T> builder = new SpecificationBuilder<>(specClazz);
Pattern pattern = Pattern.compile("(\\w+.*?)(==|!=|<|<=|>|>=|=|===)((\\*|\\w+).*?);");
Matcher matcher = pattern.matcher(search + ";");
while (matcher.find()) {
builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
}
org.springframework.data.jpa.domain.Specification<T> spec = builder.build();
Page<T> page = repository.findAll(spec, pageable);
return page;
}
...
数据库是Mysql。如果我通过Workbench在MySql中搜索straigh,我可以看到以下示例:
select created_date from releases
'0000-00-00 00:00:00'
'0000-00-00 00:00:00'
...
'2013-09-28 09:19:23'
'2013-09-28 09:19:59'
通过锁定关闭格式,我认为LocalDateTimeSerializer.serialize是正确的
任何线索都将不胜感激
****编辑
在仔细阅读之后,我检查了我的jar版本,就我所能看到的而言,我没有发现任何关于我的jar有问题的提示。我在下面添加了两个打印屏幕,显示了我使用的jar版本。
此外,我粘贴以下三种方法使用。这三种方法都会导致上述相同的错误
图书馆:
及
使用的方法没有任何区别:
1-从列中删除@JsonSerialize和@Converter。我的意思是:
//@JsonSerialize(using = LocalDateTimeSerializer.class)
//@Convert(converter = MovingLocalDateTimeConverter.class)
@Column(name = "created_date", nullable = false, insertable = true, updatable = false)
private LocalDateTime createdDate;
2-添加JsonSerialize。我的意思是:
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime dateTime, JsonGenerator generator,
com.fasterxml.jackson.databind.SerializerProvider provider)
throws IOException, com.fasterxml.jackson.core.JsonProcessingException {
if (dateTime == null) {
generator.writeNull();
} else {
generator.writeString(dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")));
}
}
}
3-添加转换器。我是说
import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter
public class MovingLocalDateTimeConverter implements AttributeConverter<LocalDateTime, String> {
//private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
@Override
public String convertToDatabaseColumn(LocalDateTime value) {
return (value != null) ? value.format(fmt) : null;
}
@Override
public LocalDateTime convertToEntityAttribute(String value) {
return convertLocalDateTime(value);
}
private LocalDateTime convertLocalDateTime(String value) {
try {
return (value != null) ? LocalDateTime.parse(value.substring(0, 19), fmt) : null;
} catch (DateTimeException e) {
return null;
}
}
}
在当前错误中,所有的可能性都没有改变。我建议您添加以下依赖项。有关更多信息,请参阅
org.hibernate
hibernate-java8
${hibernate.version}
没有任何变化。我仍然在org.hibernate.jpa.spi.BaseQueryImpl.validateBinding(BaseQueryImpl.java:897)~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]org.hibernate.jpa.internal.QueryImpl.access$000上得到“java.lang.IllegalArgumentException:参数值[2014-06-03T18:48:33]与预期类型[java.time.LocalDateTime(n/a)]]不匹配(QueryImpl.java:61)~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]“您是否删除了LocalDateTimeSerializer
?是的,我从所有java.time.LocalDateTime中删除了它(我有三个字段)。我仍然得到完全相同的错误。我正在仔细阅读,但我看不出我能做什么。此外,有趣的是,这个问题没有选择答案。我面临完全相同的问题,你解决了问题吗?如果是,你能分享解决方案吗?
//@JsonSerialize(using = LocalDateTimeSerializer.class)
//@Convert(converter = MovingLocalDateTimeConverter.class)
@Column(name = "created_date", nullable = false, insertable = true, updatable = false)
private LocalDateTime createdDate;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime dateTime, JsonGenerator generator,
com.fasterxml.jackson.databind.SerializerProvider provider)
throws IOException, com.fasterxml.jackson.core.JsonProcessingException {
if (dateTime == null) {
generator.writeNull();
} else {
generator.writeString(dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")));
}
}
}
@JsonSerialize(using = LocalDateTimeSerializer.class)
@Column(name = "created_date", nullable = false, insertable = true, updatable = false)
private LocalDateTime createdDate;
import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter
public class MovingLocalDateTimeConverter implements AttributeConverter<LocalDateTime, String> {
//private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
@Override
public String convertToDatabaseColumn(LocalDateTime value) {
return (value != null) ? value.format(fmt) : null;
}
@Override
public LocalDateTime convertToEntityAttribute(String value) {
return convertLocalDateTime(value);
}
private LocalDateTime convertLocalDateTime(String value) {
try {
return (value != null) ? LocalDateTime.parse(value.substring(0, 19), fmt) : null;
} catch (DateTimeException e) {
return null;
}
}
}
@Convert(converter = MovingLocalDateTimeConverter.class)
@Column(name = "created_date", nullable = false, insertable = true, updatable = false)
private LocalDateTime createdDate;
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-java8</artifactId>
<version>${hibernate.version}</version>
</dependency>