Spring Boot Sping Boot 3.2 + Hibernate + LocalTime

db2dz4w8  于 5个月前  发布在  Spring
关注(0)|答案(1)|浏览(108)

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

@Entity
@Getter
@Setter
public class DummyEntity {

    @Id
    private Long id;
    private String name;
    private LocalTime myTime;
}

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

var expectedMyTime = LocalTime.MAX;
    var nano = new DummyEntity();
    nano.setId(System.currentTimeMillis());
    String useCaseName = "nano";
    nano.setName(useCaseName);
    nano.setMyTime(expectedMyTime);
    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以避免截断
LocalTime adjustedMaxTime = LocalTime.of(23, 59, 59, 999_000_000);

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

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

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

相关问题