带有 java.time.LocalDate 和 DATE() 构造的 Hibernate 4

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23890687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 08:53:49  来源:igfitidea点击:

Hibernate 4 with java.time.LocalDate and DATE() construct

javahibernatejava-8

提问by drenda

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 hereand all works but I've a problem when I use DATE() construct.

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

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:

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

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
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);
    }
0(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.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.run(SelectChannelEndPoint.java:52) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608) at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:543) at java.lang.Thread.run(Thread.java:745)

I made also this test:

我也做了这个测试:

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;
  }
}

And unfortunally DATE(:test) is always null!!

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

Any suggestion is appreciated

任何建议表示赞赏

Thanks very much

非常感谢

回答by Bogoth

It appears that LocalTime, LocalDate, and LocalDateTime are not supported in Hibernate. You can, However add the functionality yourself.

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

See http://blog.progs.be/550/java-time-hibernate

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

回答by Brice Roncace

If you use JPA 2.1 this is simple to do. Converters allow your JPA entities to use the new java.time.LocalDateand java.time.LocalDateTimeclasses. Simply define the needed converter classes:

如果您使用 JPA 2.1,这很容易做到。转换器允许您的 JPA 实体使用 newjava.time.LocalDatejava.time.LocalDateTimeclasses。只需定义所需的转换器类:

LocalDatePersistenceConverter.java

LocalDatePersistenceConverter.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;
  }
}

LocalDateTimePersistenceConverter.java

LocalDateTimePersistenceConverter.java

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

And then annotate the appropriate entity property with the @Converter annotation:

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

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);


Update September 2015
Hibernate 5 natively supports the java 8 Date/Time APIs. Just ensure that the hibernate-java8jar is on your class path.

2015 年 9 月更新
Hibernate 5 本身支持 java 8 日期/时间 API。只需确保hibernate-java8jar 在您的类路径上。

回答by 0x6B6F77616C74

GOOD NEWS

好消息

There is no longer need for converters in the 5.0.0.CR2 development version. According to the official site, it supports the java8 specific data types, including java.time.LocalDate.

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

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

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

Improved bootstrapping, hibernate-java8, hibernate-spatial, Karaf support

改进的引导、hibernate-java8、hibernate-spatial、Karaf 支持

回答by Olexandra Dmytrenko

What you've got to do is convert the date into String. You may even use the java.time.LocalDate or java.time.LocalDateTime.

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

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

Output:

输出:

##代码##