spring-data-jpa无法使用java 8 LocalTime

时间:2015-03-27 11:23:52

标签: java hibernate java-8 spring-data spring-data-jpa

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

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

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

然后我要求所有实体的开始时间大于上午08:00:

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]

所以List应该包含1个元素,但它有0个元素。 如果不使用findByStartingTimeAfter我使用findByStartingTimeBefore它会返回1个元素,但我不确定是否因为我误解了前后工作方式。我已尝试使用findByStartingTimeGreaterThan,但以同样的方式失败。

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

可能是Hibernate上的问题,那就是没有正确比较VARBINARY数据(我可以看到LocalTime存储为BLOB但是它被妥善存储并检索为LocalTime)?

我使用的是postgres 9.2,但我认为问题出在postgres上。

非常感谢。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

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

中查找有关该信息的更多信息