一个cascade笔记

在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')  

 

 

你可能感兴趣的:(sql,C++,c,Hibernate,C#)