欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一个cascade笔记

程序员文章站 2023-12-28 18:17:58
...

在one-to-many设置中通常都是把many放设置位save-update,但这样会出现问题.

比如班级(Classlist)和班级公告(Notify)是一对多的关系

java 代码
  1. Session session = factory.openSession();   
  2.     Transaction tx= session.beginTransaction();   
  3.     Classlist c = (Classlist) session.load(Classlist.class, 25389l);   
  4.     Notify nofity =  new Notify();   
  5.     nofity.setClasslist(c);   
  6.     c.getNotify().add(nofity);   
  7.     nofity.setClasslist(c);   
  8.     session.save(nofity);   
  9.     tx.commit();   
  10.     session.close();  

执行的SQL语句:

sql 代码
  1. Hibernate: select classlist0_.id as id0_, classlist0_.className as className0_ from classlist classlist0_ where classlist0_.id=?   
  2. Hibernate: select notify0_.classlist_id as classlis7___, notify0_.id as id__, notify0_.id as id3_, notify0_.notify_type as notify_t2_3_, notify0_.title as title3_, notify0_.content as content3_, notify0_.accessory as accessory3_, notify0_.postDate as postDate3_, notify0_.classlist_id as classlis7_3_, notify0_.role_id as role_id3_, role1_.id as id0_, role1_.name as name0_, role1_.uri as uri0_, role1_.classlist_id as classlis4_0_, role1_.user_id as user_id0_, classlist2_.id as id1_, classlist2_.className as className1_, user3_.id as id2_, user3_.USER_TYPE as USER_TYPE2_, user3_.loginID as loginID2_, user3_.password as password2_, user3_.sex as sex2_, user3_.birthday as birthday2_, user3_.realName as realName2_, user3_.nickName as nickName2_, user3_.tel as tel2_, user3_.address as address2_, user3_.describ as describ2_, user3_.studentNumber as student12_2_ from notify notify0_ left outer join role role1_ on notify0_.role_id=role1_.id left outer join classlist classlist2_ on role1_.classlist_id=classlist2_.id left outer join users user3_ on role1_.user_id=user3_.id where notify0_.classlist_id=?   
  3. Hibernate: insert into notify (title, content, accessory, postDate, classlist_id, role_id, notify_type) values (?, ?, ?, ?, ?, ?, 'com.talent.domain.Notify')   

 

但如果是跨Session,情况就大不一样了.

 

java 代码
  1. Session session = factory.openSession();   
  2.         Transaction tx= session.beginTransaction();   
  3.         Classlist c = (Classlist) session.load(Classlist.class, 25389l);   
  4.         c.getNotify().iterator();   
  5.         tx.commit();   
  6.         session.close();   
  7.            
  8.         session = factory.openSession();   
  9.         tx= session.beginTransaction();   
  10.         Notify nofity =  new Notify();   
  11.         nofity.setClasslist(c);   
  12.         c.getNotify().add(nofity);   
  13.         nofity.setClasslist(c);   
  14.         session.save(nofity);   
  15.         tx.commit();   
  16.         session.close();  

 

sql 代码
  1. Hibernate: select classlist0_.id as id0_, classlist0_.className as className0_ from classlist classlist0_ where classlist0_.id=?   
  2. Hibernate: select notify0_.classlist_id as classlis7___, notify0_.id as id__, notify0_.id as id3_, notify0_.notify_type as notify_t2_3_, notify0_.title as title3_, notify0_.content as content3_, notify0_.accessory as accessory3_, notify0_.postDate as postDate3_, notify0_.classlist_id as classlis7_3_, notify0_.role_id as role_id3_, role1_.id as id0_, role1_.name as name0_, role1_.uri as uri0_, role1_.classlist_id as classlis4_0_, role1_.user_id as user_id0_, classlist2_.id as id1_, classlist2_.className as className1_, user3_.id as id2_, user3_.USER_TYPE as USER_TYPE2_, user3_.loginID as loginID2_, user3_.password as password2_, user3_.sex as sex2_, user3_.birthday as birthday2_, user3_.realName as realName2_, user3_.nickName as nickName2_, user3_.tel as tel2_, user3_.address as address2_, user3_.describ as describ2_, user3_.studentNumber as student12_2_ from notify notify0_ left outer join role role1_ on notify0_.role_id=role1_.id left outer join classlist classlist2_ on role1_.classlist_id=classlist2_.id left outer join users user3_ on role1_.user_id=user3_.id where notify0_.classlist_id=?   
  3. Hibernate: insert into notify (title, content, accessory, postDate, classlist_id, role_id, notify_type) values (?, ?, ?, ?, ?, ?, 'com.talent.domain.Notify')   
  4. Hibernate: update classlist set className=? where id=?   
  5. Hibernate: update notify set title=?, content=?, accessory=?, postDate=?, classlist_id=?, role_id=? where id=?   
  6. Hibernate: update notify set title=?, content=?, accessory=?, postDate=?, classlist_id=?, role_id=? where id=?   
  7. Hibernate: update notify set title=?, content=?, accessory=?, postDate=?, classlist_id=?, role_id=? where id=?   
  8. Hibernate: update notify set title=?, content=?, accessory=?, postDate=?, classlist_id=?, role_id=? where id=?   
  9. Hibernate: update notify set title=?, content=?, accessory=?, postDate=?, classlist_id=?, role_id=? where id=?  

为什么第二种情况会多了这么多UPDATE呢?

1.因为在classlist被第一个session关闭,classlist变成了游离对象,没有被session关联。
2.在nofity.setClasslist(c)时候,classlist被关联到Session中成为po.
3.因为配置文件中many方设置的cascade选项是save-update,classlist会被结连更新
4.当classlist被更新的时候,由于one方设置的也是save-update,所以和classlist相互关联的notify也会被更新

如果我们把many方设置为none就可以了。

但这样又会产生问题,如果我们保存notify,Hibernate会报一个异常,提示引用了一个未保存的临时对象。

解决的方法可以是每次都保存one的那边.

java 代码
  1. Session session = factory.openSession();   
  2.     Transaction tx= session.beginTransaction();   
  3.     Classlist c = new Classlist();   
  4.     Notify notify =  new Notify();   
  5.   
  6.     c.getNotify().add(notify);   
  7.     notify.setClasslist(c);   
  8.     session.save(c);   
  9.     tx.commit();   
  10.     session.close();  
sql 代码
  1. insert into classlist (className) values (?)   
  2. insert into notify (title, content, accessory, postDate, classlist_id, role_id, notify_type) values (?, ?, ?, ?, ?, ?, 'com.talent.domain.Notify')  

 

 

上一篇:

下一篇: