您的位置:首页 > 其它

Hibernate学习笔记 merge()方法--add对象

2009-01-19 15:30 387 查看
merge

add操作

背景:
Account 和 Group 两个对象,设置了双向的many-to-many关系,lazy=true
不使用open session in view 模式
不使用hibernate二级缓存

考虑web应用场景,设置account和group关联时,只需要group和account的id就够了。
数据库中存在两个group: 1.administrators, 2.engineers
而po对象中,group信息为:1.invalid, 2.any one

代码A:
Account account = (Account) getHibernateTemplate().merge(po);
Long id = account.getId();
System.out.println("/tGet obj after added in dao start ...");
Account readAccount = (Account) getHibernateTemplate().get(
Account.class, id);
System.out.println("/tGet obj after added in dao end ...");
System.out.println("/tIs po==readAccount ? " + (po == readAccount));
System.out.println("/tShow detai of po: " + po.toDetailString());
System.out.println("/tShow detai of readAccount: " + readAccount.toDetailString());


其中,为po设置了两个group

输出结果:
Hibernate: select ... from SYS_GROUPS where ID=?
Hibernate: select ... from SYS_GROUPS where ID=?
Get obj after added in dao start ...
Get obj after added in dao end ...
Is po==readAccount ? false
Show detai of po: Account[0.account_22, groups[2.any one 1.invalid ]]
Show detai of readAccount: Account[22.account_22, groups[2.engineers 1.administrators ]]
Hibernate: insert into SYS_ACCOUNTS (...) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into SYS_GROUP_MEMBER (ACCOUNT_ID, GROUP_ID) values (?, ?)
Hibernate: insert into SYS_GROUP_MEMBER (ACCOUNT_ID, GROUP_ID) values (?, ?)


代码B:

Long id = (Long) getHibernateTemplate().save(po);
System.out.println("/tGet obj after added in dao start ...");
Group group = (Group)getHibernateTemplate().get(Group.class,new Long(1));
System.out.println("/tGroup detai:" + group.toString());
Account readAccount = (Account) getHibernateTemplate().get(
Account.class, id);
System.out.println("/tGet obj after added in dao end ...");
System.out.println("/tIs po==readAccount ? " + (po == readAccount));
System.out.println("/tShow detai of po: " + po.toDetailString());
System.out.println("/tShow detai of readAccount: "
+ readAccount.toDetailString());

getHibernateTemplate().merge(readAccount);
Account readAgain = (Account) getHibernateTemplate().get(Account.class,
id);
System.out.println("/tIs po==readAgain ? " + (readAgain == po));
System.out.println("/tIs readAgain== readAccount? "
+ (readAgain == readAccount));
System.out.println("/tShow detai again: " + readAgain.toDetailString());


输出结果:
Get obj after added in dao start ...
Hibernate: select ... from SYS_GROUPS where ID=?
Group detai:Group 1. administrators
Get obj after added in dao end ...
Is po==readAccount ? true
Show detai of po: Account[27.account_27, groups[1.invalid 2.any one ]]
Show detai of readAccount: Account[27.account_27, groups[1.invalid 2.any one ]]
Hibernate: select ... from SYS_GROUPS where ID=?
Is po==readAgain ? true
Is readAgain== readAccount? true
Show detai again: Account[27.account_27, groups[1.administrators 2.engineers ]]
Hibernate: insert into SYS_ACCOUNTS (...) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into SYS_GROUP_MEMBER (ACCOUNT_ID, GROUP_ID) values (?, ?)
Hibernate: insert into SYS_GROUP_MEMBER (ACCOUNT_ID, GROUP_ID) values (?, ?)


结论:

1. merge()方法会导致执行查询group对象的select语句,在调用merge()命令时立即执行(条件:目标group对象没有被缓存)

2. 无论merger()或save()方法,insert语句都在最后执行,并非在调用相应命令时立即执行

3. 直接调用merge()方法时,会返回一个新的instance,原po保持不变

4. save()之后,po中的group对象并没有被关联到session,因此查询group(id=1)会触发select语句

5. save()之后,po对象被关联到session,再次查询,不会触发select语句,并且不会检查group对象是否被关联到session

6. save()之后再调用merge,返回的是同一个instance,但其关联group对象会被更新

如果在add一个对象之后,如果存在关联对象,并且需要再同一个hibernate session中进行回显,则建议使用merge()方法。

参考:
Hibernate Session.merge() javadoc
open session in view 模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐