MySQL Hibernate 不遵循 MySQL 自增主键字段
阅读更多:MySQL 教程
问题描述
在使用 Hibernate 连接 MySQL 数据库时,发现数据表中的自增主键字段无法正常自增,导致插入数据时出现主键冲突的错误。
错误示例:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'
问题分析
- MySQL 自增主键字段与 Hibernate 的 ID 生成策略不匹配
- Hibernate 自己维护了一个 ID 缓存,导致与 MySQL 的自增计数器不同步,从而生成了重复的主键值
解决方法
方法一:修改 ID 生成策略
在 Hibernate 配置文件中指定 ID 生成策略为 MySQL 的自增策略。修改方式如下:
<id name="id" type="java.lang.Long">
<column name="id" />
<generator class="native" />
</id>
将 generator class 属性的值改为 “identity” 或 “native”。
这两种生成策略都会使用 MySQL 的自增计数器来产生 ID 值,确保与数据库中的主键值保持同步。
方法二:关闭 Hibernate 的 ID 缓存
在 Hibernate 的配置文件中添加以下属性设置:
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_query_cache">false</property>
这些设置将关闭 Hibernate 的二级缓存和查询缓存,避免了缓存带来的主键冲突问题。
方法三:修改 MySQL 主键字段定义
修改 MySQL 数据库中主键字段的定义,强制设置其为非缓存类型,即每次插入数据时都重新计算其值。修改方式如下:
ALTER TABLE `tablename` MODIFY `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT;
其中, tablename 是数据表名称,id 是自增主键字段名。修改后的字段类型必须为 BIGINT,否则可能会因溢出而导致主键超出范围。
总结
MySQL Hibernate 不遵循 MySQL 自增主键字段,有以下几种解决方法:
- 修改 ID 生成策略,以使用 MySQL 的自增计数器来生成 ID 值
- 关闭 Hibernate 的 ID 缓存,避免与 MySQL 的计数器发生冲突
- 修改 MySQL 主键字段定义,强制设置其为非缓存类型
根据具体情况选择适合自己的解决方法,并注意对数据表和代码的影响。
极客教程