简体   繁体   English

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

[英]Copying TIMESTAMP to DATETIME on MySQL with Hibernate

I have these two classes 我有这两个班

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;
}

When using Hibernate, I assign 使用Hibernate时,我指定

destination.myInstant = source.myInstant;

and then the stored value is smaller by one hour than the original - both according to the command line MySQL client and in Java. 然后存储的值比原始值小1小时 - 根据命令行MySQL客户端和Java。 My current timezone is UTC+1, so the reason is obviously a timezone conversion. 我当前的时区是UTC + 1,所以原因显然是时区转换。

There are a few places where this can be fixed, but I'm looking for the best practice. 有几个地方可以修复,但我正在寻找最好的做法。 The server should work world-wide, so it should continue to use UTC internally, right? 服务器应该在全球范围内工作,所以它应该继续在内部使用UTC,对吧?

Should I just change the column type to TIMESTAMP ? 我应该只将列类型更改为TIMESTAMP吗? Then, why does Instant by default map to DATETIME ? 那么,为什么Instant默认映射到DATETIME


According to this article , Instant does map to TIMESTAMP , but in my case it did not. 根据这篇文章Instant 映射到TIMESTAMP ,但在我的情况下却没有。 Why? 为什么?

If you want to work with timezones and Java 8 I would recommend using ZonedDateTime or OffsetTimeZone (the latter being prefered when working with Hibernate). 如果你想使用时区和Java 8,我建议使用ZonedDateTime或OffsetTimeZone (后者在使用Hibernate时更喜欢)。 For older versions use Calendar. 对于旧版本,请使用日历。

  • When you instance it should go by default with the timezone of your computer. 实例时,它应默认使用计算机的时区。
  • Check if the database is timestamp with or without timezone. 检查数据库是否为带时区或无时区的时间戳。
  • The default you set is also without timezone, and if it is "with timezone" it should automatically add the database's offset. 您设置的默认值也没有时区,如果它是“with timezone”,它应该自动添加数据库的偏移量。

I hope some of this works. 我希望其中一些有用。 Here's how I did in one of my projects. 以下是我在其中一个项目中的表现。

@Column(name = "registration_time")
private OffsetDateTime registrationTime;
[...]
subscriber.setRegistrationTime(OffsetDateTime.now());

In MySQL 5 & above, TIMESTAMP values are converted from the current time zone to UTC for storage, and converted back from UTC to the current time zone for retrieval. 在MySQL 5及以上版本中,TIMESTAMP值从当前时区转换为UTC以进行存储,并从UTC转换回当前时区以进行检索。 This occurs only for the TIMESTAMP data type but not for DATETIME. 这仅适用于TIMESTAMP数据类型,但不适用于DATETIME。 This is the reason you are seeing the difference while assigning a TIMESTAMP to DATETIME. 这是您在将TIMESTAMP分配给DATETIME时看到差异的原因。 So, having both the columns of same type should work. 因此,同时使用相同类型的列应该可行。 Hibernate by default maps InstantType to database TIMESTAMP type. 默认情况下,Hibernate将InstantType映射到数据库TIMESTAMP类型。 Though you could use it for both TIMESTAMP and DATETIME in MYSQL, they are handled differently. 虽然您可以在MYSQL中将它用于TIMESTAMP和DATETIME,但它们的处理方式不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM