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

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

  session = this.getSession();
tx = session.beginTransaction();

session.delete(handset);
tx.commit();


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

  session = this.getSession();
tx = session.beginTransaction();
//删除级联关系!!
List<CheckLock> checkLocks = session.createQuery("from CheckLock cl where cl.handset.handsetId = "+
handset.getH andsetId()).list();
for(int i =0 ; i<checkLocks.size() ; i++){
checkLocks.get(i).setHandset(null);
}
session.delete(handset);
tx.commit();


结果会报:a different object with the same identifier value was already associated with the session

问题原因:这是由于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的删除方法:
int i = session.createQuery("delete Handset hs where hs.handsetId = " + handsetId).executeUpdate();
返回的是更新(删除)的记录数。不过 executeUpdate 方法是直接单独执行的,它不会等待事物的提交。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值