spring-data-jpa 不适用于 java 8 LocalTime

spring-data-jpa not working with java 8 LocalTime

Spring 数据存储库(版本 1.8)的查询派生机制无法与 Java 8 LocalTime 一起正常工作。有人可以告诉我我做错了吗还是错误?

我将开始时间存储在10:00上午

LocalTime startingTime = LocalTime.of(10,0); 
myEntity.setHorai(startingTime);
myEntityRepository.save(myEntity);

然后我询问所有开始时间大于 08:00 am:

的实体
LocalTime zeroEight = LocalTime.of(8, 0);
List<MyEntity> ents = myEntityRepository.findByStartingTimeAfter(zeroEight);

我可以看到 Hibernate(我使用的是 Hibernate 4.3 版。7.Final)执行此操作:

Hibernate: select <all fields> from MyEntity m_ where m_.startingTime>?
TRACE 2015-03-27 12:08:51,283 o.h.type.descriptor.sql.BasicBinder: binding parameter [1] as [VARBINARY] - [08:00]

所以列表应该包含 1 个元素,但它有 0 个元素。 如果不是 findByStartingTimeAfter 我使用 findByStartingTimeBefore 它 returns 1 个元素,但我不确定这是不是因为我误解了前后的工作方式。我试过 findByStartingTimeGreaterThan 但同样失败了。

也许查询派生机制不适用于 Java 8 LocalTime?

可能是 Hibernate 的问题,即没有正确比较 VARBINARY 数据(我可以看到 LocalTime 存储为 BLOB,但它作为 LocalTime 正确存储和检索)?

我正在使用 postgres 9.2,但我认为问题不在 postgres 上。

答案在问题中。 Hibernate 还不支持 java.time 类(它将在 5.0 版中提供)。因此它将 LocalTime 视为 Serializable 实例,并将序列化的 LocalTime 实例作为字节数组简单地存储在 varbinary 列中。因此,> 运算符对此类列没有多大意义,也不会按时间顺序比较 LocalTime 值。

您可以定义自己的自定义 Hibernate 类型,或使用 jadira(为您定义此自定义类型),以将 LocalTime 值存储在适当的列类型中。

如果没有进一步的映射信息,Hibernate 会将 JDK 8 个日期视为 BLOB,因此不能再对这些字段应用任何比较操作。

一个解决方案是使用 Jadira User Types library 自定义这些类型映射到数据库的方式。

如果您只处理非时区类型(例如 LocalDateLocalDateTime),最简单的方法是使用 Spring 数据附带的 JPA 2.1 转换器JPA 1.8。只需确保 Jsr310JpaConverters 是持久性 classes 的列表(通过扫描相应的包或在您的 persistence.xml 中手动列出 class)和这些 JDK 8 个特定的 date/time 类型被透明地映射到 Date,这样任何持久性提供者都可以立即持久化它们。在 blog post announcing new features in the Spring Data Fowler release train.

中找到更多相关信息