5

我将 MySQL 5.1 社区服务器更新为 5.6。在此之后,我遇到了奇怪的 DATETIME(休眠类型时间戳)行为。出于某种原因,在保存休眠映射对象后,我的日期从(例如)“2012-09-30 23:59:59”更改为“2012-10-1 00:00:00”。我的日志说我确实保存了午夜日期前的一秒,但是当我查看数据库时,它已更改为第二天的开始。如果我使用相同的日期进行 INSERT 查询,它可以正常工作。

根据 MySQL 文档,不应使用 DATETIME 进行任何时区转换。我还用 MySQL 5.5 进行了测试,但我无法重现同样的问题。

我的 hbm 映射如下所示:

<composite-id>
    ...
    <key-property name="timestamp" type="timestamp" column="timestamp"/>
</composite-id>

编辑:我也有最新的 MySQL jdbc 驱动程序。

编辑 2:如您所见,日期更改。

22.04.13 12:04:54.149 DEBUG SQL:104 - insert into data_table (col_1, col_2, timestamp) values (?, ?, ?)
22.04.13 12:04:54.149 TRACE BasicBinder:83 - binding parameter [1] as [DOUBLE] - 1.0
22.04.13 12:04:54.149 TRACE BasicBinder:83 - binding parameter [2] as [INTEGER] - 1
22.04.13 12:04:54.150 TRACE BasicBinder:83 - binding parameter [3] as [TIMESTAMP] - Mon Apr 22 23:59:59 EEST 2013
22.04.13 12:04:54.151 ERROR SqlExceptionHelper:144 - Duplicate entry '1-2013-04-23 00:00:00' for key 'PRIMARY'

编辑 3:Hibernate 版本 3.3.1 和 4.1.9 重现的问题。

4

1 回答 1

6

我想我找到了答案。我使用的日期包括毫秒,似乎在 MySQL 5.6 中您必须定义 DATETIME 的准确性。如果不定义小数的数量,它默认为 0。在这种情况下,'2013-04-01 23:59:59.500' 舍入为 '2013-04-02 00:00:00'。我设法用 sql 查询重现了这一点,因此它与 Java 或 Hibernate 无关。

http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html

我在我的代码中更改了一行

calendar.set(GregorianCalendar.MILLISECOND, 999);

calendar.set(GregorianCalendar.MILLISECOND, 0);

问题就消失了。

于 2013-04-22T11:34:48.330 回答