JPA 2.1:Java 8 Date / Time API简介

前端之家收集整理的这篇文章主要介绍了JPA 2.1:Java 8 Date / Time API简介前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想在启用了JPA的应用程序中添加Java 8 Date / Time API(JSR-310)的支持.

很明显,JPA 2.1 does not support the Java 8 Date/Time API.
作为解决方法,最常见的建议是使用AttributeConverter.

在我现有的应用程序中,我将实体更改为使用LocalDate / LocalDateTime类型作为列映射字段,并将java.util.Date的旧的setter / getter添加到它们.
我创建了相应的AttributeConverter类.

当使用Query.setParameter()与java.util.Date实例(它在转换到新的API之前工作)时,我的应用程序现在失败.似乎JPA期望新的日期类型,并且不会即时转换它.
我预计如果将参数传递给已注册了AttributeConverter的类型的setParameter(),它将被转换器自动转换.
但是似乎并非如此,至少不要使用EclipseLink 2.6.2:

java.lang.IllegalArgumentException: You have attempted to set a value of type class java.util.Date for parameter closeDate with expected type of class java.time.LocalDate from query string SELECT obj FROM [...]
    at org.eclipse.persistence.internal.jpa.QueryImpl.setParameterInternal(QueryImpl.java:937) ~[eclipselink-2.6.2.jar:2.6.2.v20151217-774c696]
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:593) ~[eclipselink-2.6.2.jar:2.6.2.v20151217-774c696]
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:1) ~[eclipselink-2.6.2.jar:2.6.2.v20151217-774c696]
  [...]

问题:

这个行为是否预期?我错过了什么?
>有没有办法使用新的日期类型作为字段,而不会破坏现有的代码
>您是如何处理在JPA中过渡到新的Date / Time API?

更新:
但是,似乎至少使用EclipseLink,存在AttributeConverter的自定义类型不完全支持
在JPQL查询中,实际的字段类型和转换的数据库类型都不能用作参数.
使用转换的数据库类型时,会发生上述异常.
当使用实际的字段类型(例如LocalDate)时,它直接传递给不知道此类型的jdbc驱动程序:

Caused by: java.sql.sqlException: Invalid column type
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:10495) 
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9974) 
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:10799) 
    at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:10776) 
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:241)
    at org.eclipse.persistence.internal.databaseaccess.DatabasePlatform.setParameterValueInDatabaseCall(DatabasePlatform.java:2506)

我希望EclipseLink使用AttributeConverter将字段类型转换为java.sql类型.
(另见这个bug报告:https://bugs.eclipse.org/bugs/show_bug.cgi?id=494999)

这导致我们最重要的问题#4:

>有没有解决方法/解决方案来支持使用EclipseLink的java 8日期字段,包括在这样一个字段上使用查询参数的可能性?

附加信息

> AttributeConverter used (for LocalDateTime conversion)
> Additional information to reproduce exception

解决方法

前段时间,我将Java EE 7 Web应用程序从Java 7转换为Java 8,并在LocalDate和LocalDateTime的实体中替换了java.util.Date.

>是的,这个行为是预期的,因为AttributeConverter只能在用于实体字段的类型和数据库类型(即java.sql.Date等)之间进行转换;它不会在查询参数中使用的实体字段类型和java.util.Date之间进行转换.
>据我所知,不,在向JPA实体中引入java.time类型之后,没有办法继续在现有代码中继续使用java.util.Date.
>除了创建必要的AttributeConverter实现之外,我将java.util.Date的所有出现次数更改为适当的java.time类型,不仅在实体中,而且还在JPA-QL查询和业务方法中.

对于项目2,当然可以通过使用在java.util和java.time之间转换的实用程序方法和getter / setter来进行某种改变,但是不会一直发生.更重要的是,如果您不愿意转换剩余的使用这些代码代码,我不太明白将java.time类型引入到JPA实体属性属性.在Java EE应用程序进行转换后,没有使用任何java.util.Date(尽管我也必须为JSF创建转换器).

猜你在找的Java相关文章