`
fcmfcm01
  • 浏览: 65748 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Hibernate 的主键生成机制与MySQL4.0使用SQL语句恢复的问题

阅读更多

最近在做项目的时候遇到一个问题,客户在使用Hibernate往数据库插入记录时总是遇到这样的错误信息:

Caused by: net.sf.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
 at net.sf.hibernate.exception.ErrorCodeConverter.convert(ErrorCodeConverter.java:73)
 at net.sf.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
 at net.sf.hibernate.impl.BatcherImpl.convert(BatcherImpl.java:328)
 at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:135)
 at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2438)
 at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2396)
 at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2261)
 
 ... 3 more
Caused by: java.sql.BatchUpdateException: Duplicate entry '42808-0' for key 1
 at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:894)
 at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:294)
 at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:54)
 at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:128)
 ... 7 more

 

而这个问题在本地测试时并未出现,开始时猜测是客户的数据库结构与本地的数据库结构不同造成的,可是经过比对,客户的数据库结构和环境与本地完全一样。

接下来分析数据库中的数据库中的数据,发现在几个表中存在垃圾数据。为了说明情况,我们假定A表中有垃圾数据,A与B、C表通过外键关联(用的是MySQL4.0,我自己不太了解,似乎没有5.0来的那么严格),然而,有意思的是在B、C表中并没有相关的数据,而且A中相关记录的PK明显大于B、C表中的最大PK。

由于B、C两个表的主键由Hibernate生成,采用的生成机制是identity,因此,主键的生成实际上是依赖于MySQL数据库本身。对于MySQL而言,数据库本身会维护本身的index,如果数据库的当前的最大的index是2000,即使删除了后一千条数据,新生成的数据也应该从2001开始。反过来,既然在A表中存在大于B、C表中最大PK的记录,那么说明A中这些个对应记录的至少曾经在B、C表存在过,那么在重新生成时,不应该出现重复的记录出现才对啊!

继续检查代码,发现A表是在B、C生成的时候自动生成的,但是删除的时候却忘了删除,但是即使这样,也不该出现先前提到的情况啊!

询问客户的数据库的情况,才知道,客户的数据库是新装了之后用以前的SQL备份文件恢复的!这下终于找到症结了,使用SQL恢复时并将相应表的Index生成记录也恢复,以至于垃圾数据与现有的新生成的数据冲突了!

二话不说,先删除垃圾数据,本来想一条SQL搞定的,无奈4.0不支持增量查询,delete的where字句也不能使用in\not in作为谓词,晕,写程序吧,经过一个小时左右,各个功能搞定!OK

后来想起来,这个问题在平常使用时经常存在,总结一下吧:

  1. 级联删除要正确的配置
  2. 数据库的备份SQL慎用,尤其是在与数据库本身主键生成相关的项目。
  3. 数据库的数据一致性很重要
分享到:
评论

相关推荐

    Hibernate笔记 马士兵

    第12课 使用hibernate工具类将对象模型生成关系模型 19 第13课 ID主键生成策略 20 一、 Xml方式 20 元素(主键生成策略) 20 二、 annotateon方式 21 1、AUTO默认 21 2、IDENTITY 22 3、SEQUENCE 22 4、为Oracle指定...

    Hibernate注解

    * 1.native 对于orcale采用Sequence方式,对于MySQL和SQL Server采用identity(处境主键生成机制), * native就是将主键的生成工作将由数据库完成,hibernate不管(很常用) * 例:@GeneratedValue(generator = ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

    6.4 Hibernate的内置标识符生成器的用法  6.4.1 increment标识符生成器  6.4.2 identity标识符生成器  6.4.3 sequence标识符生成器  6.4.4 hilo标识符生成器  6.4.5 native标识符生成器  6.5 映射自然主键  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

    6.4 Hibernate的内置标识符生成器的用法  6.4.1 increment标识符生成器  6.4.2 identity标识符生成器  6.4.3 sequence标识符生成器  6.4.4 hilo标识符生成器  6.4.5 native标识符生成器  6.5 映射自然主键  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

    6.4 Hibernate的内置标识符生成器的用法  6.4.1 increment标识符生成器  6.4.2 identity标识符生成器  6.4.3 sequence标识符生成器  6.4.4 hilo标识符生成器  6.4.5 native标识符生成器  6.5 映射自然主键  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

    6.4 Hibernate的内置标识符生成器的用法  6.4.1 increment标识符生成器  6.4.2 identity标识符生成器  6.4.3 sequence标识符生成器  6.4.4 hilo标识符生成器  6.4.5 native标识符生成器  6.5 映射自然主键  ...

    支持多数据库的ORM框架ef-orm.zip

    EF中除了Criteria API以外,可以直接使用“SQL语句”或者“SQL片段”。但是这些SQL语句并不是直接传送给JDBC驱动的,而是 有着一个数据库方言层,经过方言层处理的SQL语句,就具备了在当前数据库上正确操作的能力。...

    基于SpringJDBC的轻量级ORM框架sborm.zip

    QueryBudiler,使得更多简单的单表查询可以通过对象组织查询、更改逻辑,避免过多去写相似性的SQL语句,减少DAO接口量。 三、一些亮点 1、Entity的设计:很多人看了也许会说,这个不是POJO,不是纯粹的Java ...

    解决Hibernate JPA中insert插入数据后自动执行select last_insert_id()

    在插入数据后SQL执行日志中会多出一条select语句: 代码如下:Hibernate: insert into click_statstic (logDate, memoId, src, typeId) values (?, ?, ?, ?)Hibernate: select last_insert_id()表中有个主键是自增列...

    sqltoy-orm框架系统-其他

    sqltoy-orm是比hibernate+myBatis更加贴合项目的orm框架,具有hibernate增删改的便捷性同时也具有比myBatis更加灵活优雅的自定义sql查询功能。 sqltoy-orm支持以下数据库: oracle 从oracle11g到19c db2 9.5+,建议从...

    Java面试宝典2020修订版V1.0.1.doc

    32、SQL语句执行顺序 51 33、null的含义 52 34、mysql分页 52 35、MySQL、SqlServer、oracle写出字符存储、字符串转时间 52 36、update语句可以修改结果集中的数据吗? 53 37、oracle如何设置主键自动增长? 53 38、...

    java毕业设计_车辆紧急救援系统

    车辆紧急救援系统mysql数据库创建语句 车辆紧急救援系统oracle数据库创建语句 车辆紧急救援系统sqlserver数据库创建语句 车辆紧急救援系统spring+springMVC+hibernate框架对象(javaBean,pojo)设计 车辆紧急救援系统...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    1、将业务层与表示层分离:使用JSP技术,网络开发人员可充分使用HTML来设计页面显示部分(如字体颜色等),并使用JSP指令或者JAVA程序片段来生成网页上的动态内容; 2、能够跨平台:JSP支持绝大部分平台,包括现在...

    springmybatis

    其实还有更简单的方法,而且是更好的方法,使用合理描述参数和SQL语句返回值的接口(比如IUserOperation.class),这样现在就可以至此那个更简单,更安全的代码,没有容易发生的字符串文字和转换的错误.下面是详细...

    Java学习笔记-个人整理的

    {1.13.3}打包备份与恢复}{42}{subsection.1.13.3} {1.13.3.1}\texttt {tar},\texttt {gzip}}{42}{subsubsection.1.13.3.1} {1.13.3.2}\texttt {zip}}{42}{subsubsection.1.13.3.2} {1.13.3.3}文本创建与编辑}{43...

    JAVA上百实例源码以及开源项目源代码

    2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户...

    JAVA上百实例源码以及开源项目

    2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户...

Global site tag (gtag.js) - Google Analytics