一个cascade笔记
程序员文章站
2023-12-28 18:17:58
...
在one-to-many设置中通常都是把many放设置位save-update,但这样会出现问题.
比如班级(Classlist)和班级公告(Notify)是一对多的关系
java 代码
- Session session = factory.openSession();
- Transaction tx= session.beginTransaction();
- Classlist c = (Classlist) session.load(Classlist.class, 25389l);
- Notify nofity = new Notify();
- nofity.setClasslist(c);
- c.getNotify().add(nofity);
- nofity.setClasslist(c);
- session.save(nofity);
- tx.commit();
- session.close();
执行的SQL语句:
sql 代码
- Hibernate: select classlist0_.id as id0_, classlist0_.className as className0_ from classlist classlist0_ where classlist0_.id=?
- 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=?
- Hibernate: insert into notify (title, content, accessory, postDate, classlist_id, role_id, notify_type) values (?, ?, ?, ?, ?, ?, 'com.talent.domain.Notify')
但如果是跨Session,情况就大不一样了.
java 代码
- Session session = factory.openSession();
- Transaction tx= session.beginTransaction();
- Classlist c = (Classlist) session.load(Classlist.class, 25389l);
- c.getNotify().iterator();
- tx.commit();
- session.close();
- session = factory.openSession();
- tx= session.beginTransaction();
- Notify nofity = new Notify();
- nofity.setClasslist(c);
- c.getNotify().add(nofity);
- nofity.setClasslist(c);
- session.save(nofity);
- tx.commit();
- session.close();
sql 代码
- Hibernate: select classlist0_.id as id0_, classlist0_.className as className0_ from classlist classlist0_ where classlist0_.id=?
- 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=?
- Hibernate: insert into notify (title, content, accessory, postDate, classlist_id, role_id, notify_type) values (?, ?, ?, ?, ?, ?, 'com.talent.domain.Notify')
- Hibernate: update classlist set className=? where id=?
- Hibernate: update notify set title=?, content=?, accessory=?, postDate=?, classlist_id=?, role_id=? where id=?
- Hibernate: update notify set title=?, content=?, accessory=?, postDate=?, classlist_id=?, role_id=? where id=?
- Hibernate: update notify set title=?, content=?, accessory=?, postDate=?, classlist_id=?, role_id=? where id=?
- Hibernate: update notify set title=?, content=?, accessory=?, postDate=?, classlist_id=?, role_id=? where id=?
- 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 代码
- Session session = factory.openSession();
- Transaction tx= session.beginTransaction();
- Classlist c = new Classlist();
- Notify notify = new Notify();
- c.getNotify().add(notify);
- notify.setClasslist(c);
- session.save(c);
- tx.commit();
- session.close();
sql 代码
- insert into classlist (className) values (?)
- insert into notify (title, content, accessory, postDate, classlist_id, role_id, notify_type) values (?, ?, ?, ?, ?, ?, 'com.talent.domain.Notify')
推荐阅读
-
一个cascade笔记
-
Win10 Mobile/PC一周年14393.105有望成为下一个累积更新
-
用PHP开发C/S结构(一个简单的例子)
-
经过脚本请一个网页和浏览器访问网页,速度有没有差别
-
java当中JDBC当中请给出一个sql server的dataSource的helloworld例子
-
pygame学习笔记(5):游戏精灵
-
[ASP.NET Core 3.0学习笔记] - SignalR
-
PHP函数实现从一个文本字符串中提取关键字的方法,
-
Ext第一周 史上最强学习笔记---GridPanel(基础篇)_YUI.Ext相关
-
QQ音乐 在一个页面点击 另一个页面开始播放 不刷新 并且只打开一个