问题描述
各位大侠。小弟最近做个应用,我在页面进行数据删除的时候出了一些问题,希望各位帮忙看看! 具体情况:我的应用是基于struts2+spring2.5+hibernate3.2.我的数据库表是通过hibernate生成的,在映射文件上做了相关的关联映射。一个目录表(category),一个文章表(article)。一个目录对应多个文章。我在页面上测试删除目录的时候发现我删除那些还未发布文章的目录可以删除成功,删除已经有文章的目录不成功(意料之内)。奇怪的地方出来了,当我先删除有文章的目录不成功后再去删除无文章的目录便出现了异常,导致不能成功删除。然后我重启tomcat,直接先删除无文章的目录。顺利删除。但只要我先删除已有文章的目录出现异常后再去删除无文章的目录就删除不成功。我想有一个可能解决方案就是对删除关联数据进行一下外键依赖处理。应该就不会出现这种情况。但是我想这应该不是最好的解决办法,因为我发现在第一次出现异常后再进行删除操作时hibernate的session值取不到了。我用的是sessionFactory session 删除方法:session.getCurrentSession().delete(session.getCurrentSession().get(category.class,id)); 可能有描述得不清晰的地方,希望各位能看看!谢谢! 问题补充:韩悠悠 写道
解决方案
Session执行一些sql语句把内存中的对象的状态同步到数据库,这个过程被称为session清理.在默认情况下,Session会在下面的时间点清理缓存。1 当应用程序调用net.sf.hibernate.Transacation的commit()方法的时候,commit()方法先清理缓存,然后再向数据库提交事务。 2 当应用程序调用Session的find()或者iterate()时,如果缓存中持久化对象的属性发生了变化,就会先清理缓存,以保证查询结果能反映持久化对象的最新状态。 3 当应用程序显示调用Session的flush()方法的时候。 注意Session的commit()和flush()方法的区别。flush()方法进行清理缓存的操作,执行一系列的SQL语句,但不会提交事务;commit()方法会先调用flush()方法,然后提交事务。提交事务意味着对数据库所做的更新被永久保存下来。执行session清理的顺序:1.按照应用程序调用session.save()方法的衔后顺序,执行所有对实进行插入的insert语句。2.执行所有对实体进行更新的update语句。3.执行所有对集合进行删除的delete语句。4.执行所有对集合元素进行删除、更新或者插入的SQL语句。5.执行所有对集合进行插入的insert语句。6.按照应用程序调用session.delete()方法的先后顺序,执行所有对实体进行删除的delete语句。Session的setFlushMode()方法用于设定清理缓存的时间点。FlushMode类定义了三种不同的清理模式:FlushMode.AUTO、FlushMode.COMMIT和FlushMode.NEVER。
解决方案二:
每次做完操作后,清理一下session,当你第一次执行操作的时候,hibernate已经把数据给你缓冲起来了,所以当你第二次在删除的时候,不过是有文章没文章他都会先去查看缓冲中有没有数据,显然是有数据,就报错了