使用Hibernate将TIMESTAMP复制到MySQL上的DATETIME

maa*_*nus 13 java mysql datetime hibernate

我有这两个班

class Source {
    // mapped to TIMESTAMP
    @Version
    @Column(columnDefinition="TIMESTAMP(3) DEFAULT '2016-01-01'")
    Instant myInstant;
}

class Destination {
    // mapped to DATETIME
    @Basic(optional=true)
    Instant myInstant;
}
Run Code Online (Sandbox Code Playgroud)

使用Hibernate时,我指定

destination.myInstant = source.myInstant;
Run Code Online (Sandbox Code Playgroud)

然后存储的值比原始值小1小时 - 根据命令行MySQL客户端和Java.我当前的时区是UTC + 1,所以原因显然是时区转换.

有几个地方可以修复,但我正在寻找最好的做法.服务器应该在全球范围内工作,所以它应该继续在内部使用UTC,对吧?

我应该只将列类型更改为TIMESTAMP?那么,为什么Instant默认映射到DATETIME


根据这篇文章,Instant 确实映射到TIMESTAMP,但在我的情况下,它没有.为什么?

小智 5

如果你想使用时区和Java 8,我建议使用ZonedDateTime或OffsetTimeZone(后者在使用Hibernate时更喜欢).对于旧版本,请使用日历.

  • 实例时,它应默认使用计算机的时区.
  • 检查数据库是否为带时区或无时区的时间戳.
  • 您设置的默认值也没有时区,如果它是"with timezone",它应该自动添加数据库的偏移量.

我希望其中一些有用.以下是我在其中一个项目中的表现.

@Column(name = "registration_time")
private OffsetDateTime registrationTime;
[...]
subscriber.setRegistrationTime(OffsetDateTime.now());
Run Code Online (Sandbox Code Playgroud)


YuV*_*uVi 1

在 MySQL 5 及以上版本中,TIMESTAMP 值从当前时区转换为 UTC 进行存储,并从 UTC 转换回当前时区进行检索。这种情况仅适用于 TIMESTAMP 数据类型,但不适用于 DATETIME。这就是您在将 TIMESTAMP 分配给 DATETIME 时看到差异的原因。因此,拥有相同类型的两列应该可以。Hibernate 默认情况下将 InstantType 映射到数据库 TIMESTAMP 类型。虽然您可以将它用于 MYSQL 中的 TIMESTAMP 和 DATETIME,但它们的处理方式不同。