最近给学校做的系统,总出现主键插入冲突的问题。主键是通过hibernate自动生成的,设置increment属性,总出现Duplicate entry的错误。搜到解决方案如下:

在网站运行在apache和tomcat的负载均衡之后,总是出现一些奇怪的问题。开始有一些Duplicate entry的错误,但没在意。
          今天又看了程序运行的错误信息,发现几乎都是Duplicate entry错误,集中出现在insert数据库的时候,insert user,insert message。看了Message类的主键生成是increment类型,看了看Hibernate的源代码 ,发现对应increment主键生成器的org.hibernate.id.IncrementGenerator类里面,是使用select max( columnName ) from tableName的方式来获取。原来的程序一直运行很好,但是在用两个Tomcat来负载均衡后却出现问题。为什么? IncrementGenerator类里面的generate()方法虽然被声明成了synchronized,但现在两个Tomcat分别运行在两台服务器的两个独立的Java虚拟机里,显然问题在这里,synchronized只能在一个独立的Java虚拟机内部有效。所以,在两个Tomcat中用 select max同时取主键,就相当于在没有synchronized的保护下,并发时就会取出相同的值,再insert就会发生dumplicate entry的错误。
          后来查看Hibernate的Reference中也提到,increment不要再集群下使用。
问题找到了,解决的办法也很简单,就是使用MySQL自己的auto_increment功能来产生主键。只需将所有Hibernate映射文件中的 increment改为native或者identity。并将数据库的主键加上auto_increment属性。
         查看MySQL 5.0的文档,在14.2.6.3中介绍说:
        14.2.6.3. How AUTO_INCREMENT Columns Work in InnoDB
      If you specify an AUTO_INCREMENT column for an InnoDB table, the table handle in the InnoDB data dictionary contains a special counter called the auto-increment counter that is used in assigning new values for the column. This counter is stored only in main memory, not on disk.
InnoDB uses the following algorithm to initialize the auto-increment counter for a table T that contains an AUTO_INCREMENT column named ai_col: After a server startup, for the first insert into a table T, InnoDB executes the equivalent of this statement:

SELECT MAX(ai_col) FROM T FOR UPDATE;

看来在给数据库主键加上auto_increment的属性后,还要重新启动一下MySQL,这样才能保证所有的auto_increment被初始化正确。
好了,开始修改,别忘了先关掉所有的Tomcat!
问题解决后的感想:

Hibernate的主键生成虽然支持很多种数据库独有的increment方式,还有他自己的select max实现的increment方式,其实这些都不是很好,假如将来真的要切换数据库,并且是在集群下运行程序,某种数据库独有的increment和 select max方式的increment都会带来问题。
Hibernate中唯一一种最简单通用的主键生成器就是uuid。虽然是个32位难读的长字符串,但是它没有跨数据库的问题,将来切换数据库极其简单方便。推荐使用!!

总结:尽信书不如无书。开源的东西有很多东西让人亦喜亦悲。不断的发现,不断的解决。

转载于:https://www.cnblogs.com/yxnchinahlj/p/3713763.html

Hibernate的increment主键生成机制带来的问题相关推荐

  1. Hibernate标识符属性(主键)生成策略全析

    数据库中的主键能够唯一识别一条记录,它可以是一个字段也可以是多个字段的组合.主键的主要作用是标识表中的一条记录,还有和其他表中的数据进行关联.数据库中的主键类型必须符合唯一性约束和非空约束.作为附加属 ...

  2. 【吐血整理】Hibernate常用的主键生成策略的原理、优缺点、应用场合

    // 此文由老猫烧须整理,其中加上本人的使用教程,如有误,欢迎指出 // 仅作学习以及备份使用,转载如带有本人整理资料请注明出处 // 欢迎大家留言交流 简介版: increment:代理主键,适合于 ...

  3. JBPM对象主键生成机制

       什么是主键 我们在建立数据库的时候,需要为每张表指定一个主键,所谓主键就是能够唯一标识表中某一行的属性或属性组,一个表只能有一个主键,但可以有多个候选索引.因为主键可以唯一标识某一行记录,所以可 ...

  4. hibernate 7大主键生成策略详解与对象状态

    一:代理主键_主键自增 1.identity 1.采用底层数据库本身提供的主键生成标识符,条件是数据库支持自动增长数据类型 2.该生成器要求在数据库中把主键定义成为自增长类型.适用于代理主键 2.in ...

  5. hibernate框架之主键生成

    一. hibernate 框架中主键的生成策略 (1)native: 表示由设置的方言决定采用什么数据库生成主键方式,根据底层数据库能力选择identity.sequence中的一个. 例如:在MyS ...

  6. hibernate笔记(三) Hibernate标识符属性(主键)生成策略全析

    2019独角兽企业重金招聘Python工程师标准>>> 其实网络有很多文章都写的很好, 只要我们去一一敲下来,那么就很容易融会贯通了,复制黏贴博客太累,大家直接看大神写的吧 : ht ...

  7. Hibernate主键生成种类

    Hibernate实体类的*.hbm.xml配置文件: 一个参考例子: <hibernate-mapping> <!-- name:实体Bean,即类名 table:实体Bean对应 ...

  8. Hibernate各种主键生成策略与配置详解 - 真的很详细啊!!

    1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...

  9. 基于按annotation的hibernate主键生成策略

    这里讨论代理主键,业务主键(比如说复合键等)这里不讨论. 一.JPA通用策略生成器 通过annotation来映射hibernate实体的,基于annotation的hibernate主键标识为@Id ...

最新文章

  1. 知识图谱、深度学习、AutoML,推荐系统与新技术结合将碰撞出怎样的火花?
  2. centos 6 编译安装httpd-2.4
  3. arcims安装配置教程
  4. Linux Shell 1/dev/null 21 含义
  5. linux 没有线程的,,Linux 到现在还是没有线程呀?
  6. 快速排序--Python实现
  7. windows+caffe(三)——求取图片的均值
  8. python使用sqlalchemy执行sql查询语句
  9. 腾讯C++程序员面试题
  10. 微信小程序开发工具显示网络错误
  11. 改变一个ppt所有的幻灯片的背景色和字体颜色
  12. 【Android】MyTool工具界面:秒表
  13. 输入成绩等级c语言,C语言实现学生成绩等级划分的方法实例
  14. 异常:No persister for的解决办法
  15. canvas教程13-使用图片
  16. 将图片上传到FTP服务器
  17. 美团 Robust 热更异常 haven‘t insert code by Robust.Cannot patch this method, method.signature
  18. C语言 - 巧解正数,负数以及零的按位取反
  19. 在人一生的成长过程中,什么才是最重要的因素?
  20. neo4j图形数据库Java应用

热门文章

  1. 腾讯杰出科学家写给2029的信:计算机视觉AI技术的爆点在哪里?
  2. BAT看上了产业互联网
  3. 专家把脉,深入分析八种前景看好的物联网业务形态
  4. 一文详解「群体机器人」中的「实体进化」到底是什么?
  5. 【转载】Java异常控制机制和异常处理原则
  6. 11.8. DOMDocument
  7. Python数据可视化——使用Matplotlib创建散点图
  8. java08 Set
  9. Mybatis基于SqlSession实现CRUD
  10. iOS App 崩溃报告符号化