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

时间:2014-05-27 13:26:04

标签: java hibernate java-8

我正在尝试在我的应用中使用LocalDate和LocalDateTime和Java 8。我正在使用Hibernate 4.3.5和Spring。 我按照这个有趣的教程here进行了所有工作但是当我使用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<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);
    }

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

感谢任何建议

非常感谢

4 个答案:

答案 0 :(得分:40)

如果您使用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<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;
  }
}

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

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

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

答案 1 :(得分:26)

好消息

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

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

  

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

答案 2 :(得分:6)

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

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

答案 3 :(得分:-2)

您需要做的是将日期转换为字符串。您甚至可以使用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