Hibernate 4使用java.time.LocalDate和DATE()构造

我正在尝试在我的应用程序中使用LocalDate和LocalDateTime与Java 8。 我正在使用Hibernate 4.3.5和Spring。 我在这里遵循了这个有趣的教程,但是当我使用DATE()构造时,我遇到了一个问题。

当我尝试做:

SELECT * FROM TABLE WHERE DATE(data)=DATE(:data) 

如果我手动创建的查询(复制和过去的查询Hibernate打印)工作正常,我总是一个空列表。 我认为问题在于Hibernate内部进行的转换; 它尝试将LocalDate转换为java.util.Date。 我告诉这个,因为如果我以这种方式更改查询:

 SELECT * FROM TABLE WHERE DATE(data)=:data 

我有这个例外:

 java.lang.IllegalArgumentException: Parameter value [2014-05-27T00:00] did not match expected type [java.util.Date (n/a)] at org.hibernate.jpa.spi.BaseQueryImpl.validateBinding(BaseQueryImpl.java:885) at org.hibernate.jpa.internal.QueryImpl.access$000(QueryImpl.java:80) at org.hibernate.jpa.internal.QueryImpl$ParameterRegistrationImpl.bindValue(QueryImpl.java:248) at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:631) at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:180) at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:49) at it.AppuntamentoCustomRepositoryImpl.findAppuntamenti(AppuntamentoCustomRepositoryImpl.java:95) 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.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) at com.sun.proxy.$Proxy91.findAppuntamenti(Unknown Source) 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.granite.messaging.service.ServiceInvocationContext.invoke(ServiceInvocationContext.java:72) at org.granite.messaging.service.security.AbstractSecurityService.endAuthorization(AbstractSecurityService.java:104) at org.granite.spring.security.SpringSecurity3Service.authorize(SpringSecurity3Service.java:289) at org.granite.messaging.service.ServiceInvoker.invoke(ServiceInvoker.java:220) at org.granite.messaging.amf.process.AMF3MessageProcessor.processRemotingMessage(AMF3MessageProcessor.java:141) at org.granite.messaging.amf.process.AMF3MessageProcessor.process(AMF3MessageProcessor.java:60) at org.granite.messaging.amf.process.AMF0MessageProcessor.process(AMF0MessageProcessor.java:79) at org.granite.messaging.webapp.AMFEndpoint.serviceJMFAMF(AMFEndpoint.java:151) at org.granite.messaging.webapp.AMFEndpoint.service(AMFEndpoint.java:64) at org.granite.spring.ServerFilter.handle(ServerFilter.java:322) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) at javax.servlet.http.HttpServlet.service(HttpServlet.java:755) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255) at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116) at org.eclipse.jetty.server.Server.handle(Server.java:370) at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494) at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982) at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240) at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:667) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543) at java.lang.Thread.run(Thread.java:745) 

我也做了这个测试:

 TypedQuery test = manager.createQuery("select DATE(:test) FROM Appuntamento", Date.class); test.setParameter("test", LocalDate.now()); for (Date t : test.getResultList()) { log.debug("T----------->" + t); } 

不幸的是DATE(:test)总是空的!

任何建议表示赞赏

非常感谢

如果您使用JPA 2.1,这很简单。 转换器允许JPA实体使用新的java.time.LocalDatejava.time.LocalDateTime类。 只需定义所需的转换器类:

LocalDatePersistenceConverter.java

 import java.time.LocalDate; import javax.persistence.AttributeConverter; import javax.persistence.Converter; @Converter public class LocalDatePersistenceConverter implements AttributeConverter { @Override public java.sql.Date convertToDatabaseColumn(LocalDate entityValue) { if (entityValue != null) { return java.sql.Date.valueOf(entityValue); } return null; } @Override public LocalDate convertToEntityAttribute(java.sql.Date databaseValue) { if (databaseValue != null) { return databaseValue.toLocalDate(); } return null; } } 

LocalDateTimePersistenceConverter.java

 import java.time.LocalDateTime; import javax.persistence.AttributeConverter; import javax.persistence.Converter; @Converter public class LocalDateTimePersistenceConverter implements AttributeConverter { @Override public java.sql.Timestamp convertToDatabaseColumn(LocalDateTime entityValue) { if (entityValue != null) { return java.sql.Timestamp.valueOf(entityValue); } return null; } @Override public LocalDateTime convertToEntityAttribute(java.sql.Timestamp databaseValue) { if (databaseValue != null) { return databaseValue.toLocalDateTime(); } return null; } } 

然后使用@Converter注释注释适当的实体属性:

 @Convert(converter = LocalDatePersistenceConverter.class) private LocalDate completedDate; 

2015年9月更新
Hibernate 5本身支持java 8 Date / Time API。 只需确保hibernate-java8 jar在您的类路径上。

好消息

5.0.0.CR2开发版中不再需要转换器。 根据官方网站,它支持java8特定的数据类型,包括java.time.LocalDate。

http://hibernate.org/orm/downloads/

改进了bootstrapping, hibernate-java8 ,hibernate-spatial,Karaf支持

似乎Hibernate不支持LocalTime,LocalDate和LocalDateTime。 但是,您可以自己添加function。

请参见http://blog.progs.be/550/java-time-hibernate

你要做的是将日期转换为String。 您甚至可以使用java.time.LocalDate或java.time.LocalDateTime。

 LocalDateTime myDate = LocalDateTime.of(2015, 04, 30, 15, 43, 12); int numberOfIdOfDate = ((Long) session.createQuery( "SELECT count(*) FROM domain.PromoCard WHERE CREATE_DATE= :my_date") .setParameter("my_date", myDate.toString()) .uniqueResult()).intValue(); log.info("Count of records with date '{}' is {}", myDate, numberOfIdOfDate); 

输出:

 [main] INFO myhibernate.PromoCardTest - Count of records with date '2015-04-30 15:43:12' is 6