You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate与MariaDB仅以秒精度存储时间戳?存Java Date遇唯一键冲突

问题分析与解决方案

这个问题我之前也碰到过,核心原因是Java Date的毫秒精度和数据库字段的精度不匹配导致的。

为什么会出现这个情况?

你用的new Date(1518458441039)和new Date(1518458441102)这两个对象,毫秒数不同,但对应的日期字符串到秒都是2018-02-12 14:00:41。如果你的MariaDB字段是默认的DATETIME类型(不带精度后缀),它只支持秒级精度,Hibernate在存储时会自动截断毫秒部分,导致两个不同的Date最终存成同一个值,触发唯一约束报错:

11:09:59.540 [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - (conn=502) Duplicate entry '2018-02-12 14:00:41' for key 'UK_plwo79yqbhw7h0yuxbrg5ru7q'
javax.persistence.PersistenceException: org.hibernate.exception.Co...

解决步骤

1. 修改数据库字段精度

首先要确保MariaDB的字段支持毫秒精度。MariaDB 10.1.2及以上版本支持带小数秒的DATETIME类型,你需要把字段改成:

ALTER TABLE your_table MODIFY COLUMN your_date_column DATETIME(3) UNIQUE;

这里(3)表示保留3位小数,也就是毫秒级精度;如果需要更高的微秒精度,可以用DATETIME(6)。

2. 同步Hibernate映射配置

接下来要让Hibernate知道字段的精度,避免截断:

  • 注解方式:在实体类的Date字段上添加@Column指定columnDefinition:
@Column(name = "your_date_column", columnDefinition = "DATETIME(3)", unique = true)
private Date yourDateField;
  • XML映射方式:在对应的字段配置里指定类型:
<property name="yourDateField" column="your_date_column" type="timestamp">
    <column name="your_date_column" sql-type="DATETIME(3)" unique="true"/>
</property>

3. (可选)改用Java 8+的时间类型

推荐使用Java 8引入的LocalDateTime代替旧的Date类,它的API更清晰,也能更好地和数据库的精度匹配。需要确保你的Hibernate版本支持Java 8(比如Hibernate 5.2+),然后配置如下:

@Column(name = "your_date_column", columnDefinition = "DATETIME(3)", unique = true)
private LocalDateTime yourDateField;

这样存储时会完整保留毫秒信息,不会出现截断问题。

内容的提问来源于stack exchange,提问作者spierepf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:55:18