摘自网上的一段解决办法。

原文:http://blog.163.com/me_wxx/blog/static/13519139120105152638477/

下面是插入数据部分的程序:

public static void main(String[] args) {
  // TODO Auto-generated method stub
  User myuser= new User();
  myuser.setName("new name2");
  System.out.print("33333");
  myuser.setPassword("33333");
  UserDAO dao = new UserDAO();
  Transaction tran=dao.getSession().beginTransaction();
  
  dao.save(myuser);
 }
改正方法:

程序错误,将程序改为:

public static void main(String[] args) {
  // TODO Auto-generated method stub
  User myuser= new User();
  myuser.setName("new name3");
  System.out.print("33333");
  myuser.setPassword("33333");
  UserDAO dao = new UserDAO();
  Transaction tran=dao.getSession().beginTransaction();
  tran.begin();
  dao.save(myuser);
  tran.commit();
 }

关于此类问题,我在网上看到了一些其他解法,虽然我没有用上,但仍然给我一些启发,现将其他解法分享如下:

http://blog.csdn.net/teabook00/archive/2010/05/09/5571848.aspx

1.背景

之前从没用过hibernate,因此在网上搜了一下hibernate快速入门方面的信息,最后我按照《Myeclipse Hibernate 快速入门 中文版》(CSDN,百度文库都有)一文开始了我的hibernate之旅(为项目做技术准备)。

下面是在学习使用时用到的三个开发工具(Myeclipse , Mysql , SQL-Front)及其版本说明:

Myeclipse版本为6.5(没用最新的Myeclipse8.5,这是由于之前组里的项目都是在Myeclipse6.5中开发的,并且本项目是与 其它人合作完成的,为了防止可能由于开发环境的不一致而引起的问题,我们统一使用Myeclipse6.5,所以我就在Myeclipse6.5环境下学 习使用hibernate了)。

Mysql使用的是5.1版本。Mysql安装完后,需要手动进行配置,其中有一项是“please select the database usage”,我在这里选择的是“Muitifunctional Database”(如下图所示)。这里其实选则的是使用何种类型的数据库(InnoDB还是MyISAM),如果选第三个,就不能用InnoDB类型的 数据库了,这个在每一个选项的说明中可以看到。

为了方便mysql的使用,又安装了图形化界面的SQL-Front,版本是5.1。

2.遇到的问题

       我用SQL-Front在数据库中建了一简单的表用于学习,等同的SQL语句如下:

“author”表有两个字段,一个是主键“Id”,一个是“name”。需要说明的是SQL-Front在建表的时候默认数据库类型为InnoDB。

针对“author”表,按照《Myeclipse Hibernate 快速入门 中文版》一文的说明操作完成后,写了一段简单的测试代码:

即插如一条name字段为“author”的数据,但是发现执行完后数据根本就没有插入到数据库中。后来在网上搜了一下,有人给出了解决办法,即使用事务来解决,修改后的代码如下:

数 据插入的问题是解决了,但是发现插入数据后,Id已经在插入前自动增加了(不是从1开始了),也就是说之前的测试虽然数据看似没有插入数据库,但是实际效 果却跟插入了数据库一样(要不然Id不会自动增加),这又是为什么?在网上搜了一下,结合自己的理解,我分析了一下原因。

3.原因

       上述问题的原因的本质我认为在于使用的数据库类型。

我使用的数据库类型是“InnoDB”,这是一个支持事务的数据库类型,这种数据库你无论什么操作,最后如果你不“commit”的话,等于啥也没干(这 其中的道理在网上搜一下对数据库中事务的简单介绍应该不难理解)。虽然通过save方法可以将sql语句发送到数据库让其执行(备注:并不是所有的 save方法都会将sql语句发送到数据库,当主键生成策略为native的时候会发送到数据库,比如“author”的主键Id,其生成策略就为 native,不过可以通过dao.getSession().flush() 强行将sql语句发送到数据库。这些我 也只是知道一点皮毛,有时间还需要深入了解),数据库也确实执行了(分配了Id,并且将Id自动加1),但是这个执行的结果只是临时的,如果不 “commit”的话,随着会话session的结束(即上述代码中dao.getSession().close()语句),这个临时的执行结果也就没 了,直接的体现就是数据没有最终插入数据库。

通过SQL-Front可以很好的观察到这一过程(针对未引入事务的那段代码),首先在dao.getSession().Close() 处 设置断点,然后用SQL-Front打开这个表,并设置SQL-Front与mysql的会话隔离级别为(Read Uncommitted,默认的级别为Repeatable Read,这个网上也有很多介绍的,也不多说了),然后执行测试代码,执行到断点处后,也即刚刚执行完dao.save(author) 而还没有关闭本次会话,通过SQL-Front会发现,这个数据插入到了表中(当然是“临时”插入数据,如果会话隔离级别不是Read Uncommitted的话是看不到这条插入的数据的),继续执行dao.getSession().close() 后,通过SQL-Front刷新“author”表中的数据,会发现刚刚插入的那条数据又消失了。

不过这其中有一个比较特殊的地方,那就是Id这个自段了。这个字段是“author”表的主键,并且它的值是数据库自己产生的,在插入数据的时候不需要指 定这个字段的值。这个字段的特殊之处在于你在插入数据的时候,无论最后是否“commit”,这个字段的值都会自动加1供下一次插入数据时使用,不会说由 于本次会话没有“commit”,而在会话结束时自动减1恢复到原来的值。

这一点我觉得应该是出于并发的考虑(没有查阅相关资料,只是提出我自己的猜测)。假设有三个会话A和B,都要向“author”表中插入数据(假设表中没 有数据,Id从1开始),A首先调用了save方法,数据库为A插入的数据分配的Id是1,然后“author”表将Id自动加1并保存,在A未 “commit”之前,B也调用了save方法,自然数据库为B插入的数据分配的Id是2(不会是1,如果是1,A和B将要提交的数据主键Id值就冲突 了,会造成A和B谁后“commit”数据谁失败,数据库就无法并发了),“author”表将Id字段再次加1后保存(此时为下一组数据使用的Id值为 3),假设B首先“commit”了数据,即“author”表中有了Id字段值为2的数据,而A最终没有“commit”数据,如果此时 “author”表的字段自动减1,可以看到,下一次数据插入分配的Id字段值就会是2,和现有的数据发成了主键冲突。因此,对于“author”表中 Id这个字段,无论某个插入操作是否最终“commit”,只要调用了save方法,Id字段就会自加1。这也能解释之前遇到的那个问题,即数据没有插 入,Id字段却自动增加了。

4.解决方法

     总共有两种解决方法:

      第一种 : 可以考虑使用“MyISAM”类型的数据库,这种类型的数据库不支持事务,因此在调用save方法的时候(注意,如果主键生成策略不是native的,必须在save后调用dao.getSession().flush() 方 法,即强行将sql语句发送到数据库,否则一样没有插入数据),数据就已经最终插入到数据库里了(注意,这是最终结果,不是临时结果,这和使用 “InnoDB”类型数据库时“commit”的效果是一样的)。当然了,直接使用事务机制(就像上面那段修改后的代码一样)也是可以的 (“MyISAM”类型的数据库虽然不支持事务,但是并不代表不能用hibernate里的事务机制,这两个概念还不太一样。当主键生成策略不是 native的时候,使用事务机制还省的调用dao.getSession().flush() 方法了)。mysql 支持“MyISAM”类型的数据库,可以在SQL-Front中直接将“InnoDB”类型的数据库转为“MyISAM”类型的数据库(建议这么做的时候 小心,因为看到网上有人说这么做可能会产生问题,不过我转换的时候倒是没碰到什么问题,也可能是我的“author”表简单的缘故),也可在建表的时候直 接指定类型为“MyISAM”。关于“MyISAM”类型的数据库的更多信息(比如相对于“InnoDB”类型数据库有什么优缺点)网上也有很多介绍,就 不在这里罗嗦了。

第二种: 还是使用“InnoDB”类型的数据库。这时可以通过两种途径解决:一是像上面那个修改后的代码一样,加入事务机制,这是最保险的(也推荐使用);第二个途径就是在hibernate的配置文件中,加入自动提交的属性,如下图所示:

这个属性的作用是,一旦调用了save方法(和第一种解决方法一样,如果主键生成策略不是native的,必须在save后调用dao.getSession().flush() 方法),hibernate会自动帮你“commit”,在代码里不需要自己写关于事务的那些代码(例如commit调用)。这么做的缺点网上也有很多说明,也不在这里多说了。

5.总结

      由于我水平实在有限(大菜鸟一个啦),表达能力也不是很好,所以说了这么多也可能还没说明白,没说透彻。不过我觉的对大家有用的一个结论就是,无论什么操作,都放在事务里提交,这样是最省事,也是最保险的。

hibernate MySQL 无法正确插入数据相关推荐

  1. mysql常见问题处理-插入数据error code:1206

    mysql常见问题处理-插入数据error code:1206 mysql  error code:1206 the total number of locks exceeds the lock ta ...

  2. mysql为什么不能插入数据_mysql为啥不能插入数据

    mysql为何不能插入数据? 安装AppServ后首次使用mysql,没有图形界面,在"MySql Command Line Client"的操作如下: ============= ...

  3. mysql数据库表插入数据

    如何向mysql数据表中插入数据? 答:你可以通过 mysql> 命令提示窗口中向数据表中插入数据,或者通过PHP脚本来插入数据. 以下为向MySQL数据表插入数据通用的 INSERT INTO ...

  4. php怎么插入数据,利用PHP怎么向MySQL数据库中插入数据

    利用PHP怎么向MySQL数据库中插入数据 发布时间:2020-12-11 16:41:47 来源:亿速云 阅读:89 作者:Leah 这篇文章给大家介绍利用PHP怎么向MySQL数据库中插入数据,内 ...

  5. hibernate+oracle+servlet实现插入数据的时候,不立马显示!!

    尊重原创!!! 开发软件:myeclipse 10+oracle 11g 开发项目:租房系统 开发人员:1111 出现的问题:在前台发布房屋信息的界面插入数据时,自动跳转到查询所有房屋信息的页面,数据 ...

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

    本文出处:http://blog.csdn.net/chaijunkun/article/details/8647281,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议在 ...

  7. MySQL中如何插入数据

    插入数据 1数据插入 2插入完整行 3插入多个行 4插入检索出的数据 1数据插入 INSERT是用来插入(或添加)行到数据库表的.插入可以用几种方式使用: 插入完整的行: 插入行的一部分: 插入多行: ...

  8. MySQL如何快速插入数据

    前言: 日常学习和工作中,经常会遇到导数据的需求.比如数据迁移.数据恢复.新建从库等,这些操作可能都会涉及大量数据的导入 有时候导入进度慢,电脑风扇狂转真的很让人崩溃,其实有些小技巧是可以让导入更快速 ...

  9. MySQL INSERT:插入数据(添加数据)

    数据库与表创建成功以后,需要向数据库的表中插入数据.在 MySQL 中可以使用 INSERT 语句向数据库已有的表中插入一行或者多行元组数据. 基本语法 INSERT 语句有两种语法形式,分别是 IN ...

最新文章

  1. Gevent异步服务类实现多姿势WEB实时展示
  2. 解决Java工程URL路径中含有中文的情况
  3. OpenCV在Linux中安装
  4. 响应文件是不是标书_什么是标书?投标书有哪些分类?标书和投标书的不同?...
  5. Java基础知识回顾之七 ----- 总结篇
  6. 重度使用Flutter研发模式下的页面性能优化实践
  7. andriod开发中的几个基本概念及关系SDK ADT Platform API
  8. Openfire性能优化与压力测试小结
  9. 问题:如何将多个文件里内容都提取出来
  10. shell逻辑运算符优先级_逻辑运算符有那些?
  11. 计算机考试策略,计算机等级考试应试的策略.doc
  12. centos 安装LibreOffice word转PDF导出
  13. android6.0加内存卡,Android 6.0 TF卡 手机扩容的新选择
  14. Growth—电子书预览版
  15. 行列式计算程序(基于Python)
  16. uniapp中页面白屏问题
  17. 开源技术分享:SDN网络浅析与选型
  18. pptpd mysql_rhel6+pptpd+freeradius+mysql
  19. python中的序列封包和序列解包
  20. 合成资产赛道风云突变,Linear Finance有望成为最具潜力的黑马

热门文章

  1. 树莓派4B通过网线连接笔记本上网
  2. 《江畔独步寻花》评课稿
  3. 编写程序,解决鸡兔同笼问题:一个笼子里关着鸡和兔子。问笼中各有多少只鸡和兔?
  4. svn——“验证位置时发生错误” e170001: 认证失败
  5. 未来感html5模板,天际ME5极具未来感设计效果图曝光
  6. Virtual Judge——C - 月之数
  7. 假如苹果公司倒闭了,会对iOS及macOS用户产生什么影响?
  8. 赋能千行百业,AI究竟走到哪一步了?
  9. JavaWeb黑马旅游网-学习笔记10【项目代码】
  10. 计算机启动异常卡顿,解决开机卡顿的问题,电脑卡在开机界面的解决办法