web-dev-qa-db-ja.com

Java.time.LocalDateおよびDATE()コンストラクトを使用したHibernate 4

LocalDateとLocalDateTimeをJava 8でアプリで使用しようとしています。Hibernate4.3.5とSpringを使用しています。この興味深いチュートリアル here とすべて動作しますが、DATE()構造を使用すると問題が発生します。

私がやろうとするとき:

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

手動で作成したクエリ(コピーおよび過去のクエリHibernate print)が正常に機能する場合も、常に空のリストがあります。問題は、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)は常にnullです!!

どんな提案も大歓迎です

どうもありがとう

28
drenda

JPA 2.1を使用する場合、これは簡単です。コンバータを使用すると、JPAエンティティで新しいJava.time.LocalDateおよびJava.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がクラスパスにあることを確認してください。

40
Brice Roncace

良いニュース

5.0.0.CR2開発バージョンでは、コンバーターは不要になりました。公式サイトによると、Java.time.LocalDateを含むJava8固有のデータ型をサポートしています。

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

ブートストラップの改善、hibernate-Java8、hibernate-spatial、Karafサポート

26
0x6B6F77616C74

LocalTime、LocalDate、およびLocalDateTimeはHibernateではサポートされていないようです。ただし、自分で機能を追加できます。

http://blog.progs.be/550/Java-time-hibernate を参照してください

6
Bogoth