2008-01-05
hibernate的context的细节地方
关键字: hiberante, 一级缓存, context作用域Hibernate的Session是它的灵魂,则Session所掌握的context作用域也是Hibernate发挥最大本领的场所。
考虑以下代码, Group与User一个典型的一对多关系:
Session session = HibernateSessionFactory.getSession();
Group g = (Group) session.get(Group.class, id);
Hibernate.initialize(g.getUsers());
session.close();
session = HibernateSessionFactory.getSession();
assertEquals("superleo", g.getName());
assertTrue(null != g.getUsers());
User u = g.getUsers().get(0);
assertEquals("rose2", u.getName());
u.setName("rose");
session.getTransaction().commit();
session.close();
与代码:
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
Group g = (Group) session.load(Group.class,
"402881ee174998f901174998fb8a0002");
assertEquals("superleo", g.getName());
assertTrue(null != g.getUsers());
User u = g.getUsers().get(0);
assertEquals("rose2", u.getName());
u.setName("rose");
session.getTransaction().commit();
session.close();
粗略的看,两段代码没有什么特别的地方,都是通过“一方”来级联更新“多方”,因此应该有不少人不会太注意这样的写法吧。仔细一看, 原来session开了两次。 刚才说了,hibernate的context是一个重要的作用域,可惜的是它的周期与具体的session绑定在一起,也就是说session.close() 就意味着一个context告一段落,再开启session的时候,当前的context与上一个是没有关系的。
上面的两段代码因此执行后的结果是有很大差别的:
第一段代码的级联操作,会遍历整个“多方”,也就是说控制台会出现N条Update语句,
第二段代码只有一条Update语句(因为我代码只更新了一个“多方”)。
原因就是我说的当对象不处于Hibernate的context,它只是一个departed对像,与当前JVM上其它new出来,或反射出来的对象没有区别了,Hibernate不会再去维护它与数据库之间的关系。所以,当保存级联操作的时候,Hibernate并不知道“多方”究竟是谁变化了,只有都update一下,才能万无一失。
不知道,你的代码更多的是哪一种写法呢?
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 91551 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
最新评论
-
用Spring2.5和ICEFaces开 ...
哈哈,多谢翻译,正在研究这方面的东西呢,看了你的文章,深有帮助
-- by jzx19770812 -
【JSF专家Dennis Byrne】 ...
to Itian:窗口之间传数据..很简单啊.. 子窗口付值到父窗口: wind ...
-- by terryzhou -
【JSF专家Dennis Byrne】 ...
不错哦..可惜看到太晚..上面两个问题都自己解决了.. 特别是MAP那个..比较 ...
-- by terryzhou -
JSF+AJAX企业级开发之路— ...
引用实际上Sun除了Java语言本身外,没有什么特别成功的东西 别忘了Sun是 ...
-- by mkclawhammer -
JSF+AJAX企业级开发之路— ...
-- by yydxl






评论排行榜