Hibernate的非延迟加载的删除写法

      由于项目比较小,因而没用延迟加载。所有的延迟都是false,这样容易造成以下问题:

session=this.getSession();

tx=session.beginTransaction();

session.delete(handset);

tx.commit();

以上的代码没有错误不过在添加级联删除后,代码如下:

session=this.getSession();

tx=session.beginTransaction();

//删除级联关系!!

List<CheckLock>checkLocks=session.createQuery("fromCheckLockclwherecl.handset.handsetid="+handset.getHandsetId()).list();

for(inti=0;i<checkLocks.size();i++){

checkLocks.get(i).setHandset(null);

}

session.delete(handset);

tx.commit();

结果会报:adifferentobjectwiththesameidentifiervaluewasalreadyassociatedwiththesession

问题原因:这是由于handset传来时是session.close的,就是说它是非持久状态的。而对于方法内部的session,由于它进行了级联查询,又由于延迟得关闭,所以当session查出CheckLock的同时也将其级联的handset对象查出并纳入session管理之中,这时就存在一条数据库记录2个handset对象的情况。一个是被传进来,非持久的不被session管理的handset,一个是通过级联查询的被session管理的handset,。所以由于你删除的是非持久化handset,它要先纳入session的管理,就是持久化但是显然此时的session内已经有个Handset对象因而会抛出上述异常

问题的解决:没什么好的解决方法,最好是传来ID之后重新查出handset删除就会没问题(以前觉得这种方式不好,会使得dao重新查询数据库。其实是我多心了,由于级联查询造就将handset存于内存中。因而Hibernate只须调用缓存即可获得结果。)

PS:查了一下hql的删除方法:

inti=session.createQuery("deleteHandsethswherehs.handsetId="+handsetId).executeUpdate();

返回的是更新(删除)的记录数。不过executeUpdate方法是直接单独执行的,它不会等待事物的提交。

相关推荐