带有 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
Hibernate 4 with java.time.LocalDate and DATE() construct
提问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.accessTypedQuery<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。您可以,但是自己添加功能。
回答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.LocalDate
and java.time.LocalDateTime
classes. Simply define the needed converter classes:
如果您使用 JPA 2.1,这很容易做到。转换器允许您的 JPA 实体使用 newjava.time.LocalDate
和java.time.LocalDateTime
classes。只需定义所需的转换器类:
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:
输出:
##代码##