Spring Boot Sping Boot 3.2 + Hibernate + LocalTime

db2dz4w8  于 2024-01-06  发布在  Spring
关注(0)|答案(1)|浏览(188)

我使用Sping Boot 3.2和Hibernate 6.3.1.Final,我有以下实体

  1. @Entity
  2. @Getter
  3. @Setter
  4. public class DummyEntity {
  5. @Id
  6. private Long id;
  7. private String name;
  8. private LocalTime myTime;
  9. }

字符串
似乎有些值没有正确保存。下面是一些示例
如果我尝试保存LocalTime.MAX,则保存的值将为“00:00”
如果我尝试保存LocalTime.MAX.withNano(999_999_000),则保存的值将为“00:00”
如果我尝试保存LocalTime.MAX.withNano(999_000_000),那么保存的值是正确的。
下面是我如何保存数据的示例

  1. var expectedMyTime = LocalTime.MAX;
  2. var nano = new DummyEntity();
  3. nano.setId(System.currentTimeMillis());
  4. String useCaseName = "nano";
  5. nano.setName(useCaseName);
  6. nano.setMyTime(expectedMyTime);
  7. dummyRepository.save(nano);


我的错在哪里?这里的github project代表了我目前的情况

ocebsuys

ocebsuys1#

这是在PostgreSQL中使用Hibernate时LocalTime.MAX舍入到00:00的已知问题。

**根本原因:**纳秒处理不一致:Hibernate内部表示LocalTime.MAX(23:59:59.99999999)可能与PostgreSQL的TIME类型冲突,后者存储精度为6位的纳秒。纳秒截断:当Hibernate持久化LocalTime.MAX时,PostgreSQL可能会截断最后3位纳秒(999),实际上是向上舍入到第二天(00:00:00.000)。
可能的解决方案:

  1. Hibernate版本6.4.1.Final和更高版本通过改进的纳秒处理解决了这个问题。如果可能,请升级。
    1.对于早期版本,将纳秒设置为999,000,000而不是999,999,999以避免截断
  1. LocalTime adjustedMaxTime = LocalTime.of(23, 59, 59, 999_000_000);

1.创建一个自定义的Hibernate类型来处理TIME值的完全纳秒精度,绕过PostgreSQL的限制
1.切换到TIMESTAMP。如果可行,考虑使用精度更高的TIMESTAMP,以实现更精确的纳秒存储

最后一招(可能不可行,但仍可以考虑):

1.探索对TIME类型具有更好的纳秒支持的替代数据库系统。
1.如果准确的LocalTime.MAX值的数据库存储并不重要,则调整应用程序逻辑以适应可能的舍入。

展开查看全部

相关问题