Hibernate 4 with java.time.LocalDate and DATE() construct
hibernate, java, java-8
Solution
If you use JPA 2.1 this is simple to do. Converters allow your JPA entities to use the new `java.time.LocalDate` and `java.time.LocalDateTime` classes. Simply define the needed converter classes:
LocalDatePersistenceConverter.java
import java.time.LocalDate;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter
public class LocalDatePersistenceConverter implements AttributeConverter<LocalDate, java.sql.Date> {
@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<LocalDateTime, java.sql.Timestamp> {
@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;
}
}
And then annotate the appropriate entity property with the @Converter annotation:
@Convert(converter = LocalDatePersistenceConverter.class)
private LocalDate completedDate;
Update September 2015 Hibernate 5 natively supports the java 8 Date/Time APIs. Just ensure that the hibernate-java8 jar is on your class path.
Problem
I'm trying to use LocalDate and LocalDateTime with Java 8 in my app. I'm using Hibernate 4.3.5 and Spring. I followed this interesting tutorial here and all works but I've a problem when I use DATE() construct. When I try to do: ``` SELECT * FROM TABLE WHERE DATE(data)=DATE(:data) ``` I've always an empty list also if the query I made manually (copy and past query Hibernate print) works fine. I think that the problem is the conversion that Hibernate do internally; it try to convert LocalDate to java.util.Date. I tell this because if I change the query in this way: ``` SELECT * FROM TABLE WHERE DATE(data)=:data ``` I've this exception: ``` 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) ``` I made also this test: ``` TypedQuery<Date> test = manager.createQuery("select DATE(:test) FROM Appuntamento", Date.class); test.setParameter("test", LocalDate.now()); for (Date t : test.getResultList()) { log.debug("T----------->" + t); } ``` And unfortunally DATE(:test) is always null!! Any suggestion is appreciated Thanks very much