我有两个类:Parent
和Child
,使用Child
拥有的关系映射一对多。我也在使用Ehcache的二级缓存。
为了坚持这种关系,我这样做:
child.setParent(parent);
session.saveOrUpdate(child);
parent.getChildren().add(child);
当我在另一个会话中加载parent
时(来自二级缓存),这个新添加的child
是否可见?在这种情况下刷新父集合的正确方法是什么?
对具有一些具体解释或链接到文档的答案的奖励积分,而不是“对我来说似乎没问题,是的”。
要明确:一切都发生在正确提交的事务中。主要问题是:这是为parent.children
和第二级缓存中的其他人刷新Session
的正确方法吗?
另一点:如何在回滚时从二级缓存中驱逐此类集合?
答案 0 :(得分:0)
您使用什么类型的缓存?
这个顺序适合我:
child.setParent(parent);
parent.getChildren().add(child);
session.saveOrUpdate(child);
session.flush();
另外,请确保您真正需要该缓存。根据我的经验,二级缓存很少加速实际应用程序,但却产生了很多问题。
答案 1 :(得分:0)
在我看来,这是因为数据库隔离的本质,未提交的内容不应该对其他数据库连接可见(在Hibernate语言中,未提交的内容不应该对其他Hibernate会话可见)。 在其他Hibernate会话中可见的是提交事务(使用Hibernate语言,提交Hibernate会话)。
Transaction tx = session.beginTransaction()
child.setParent(parent);
session.saveOrUpdate(child);
parent.getChildren().add(child);
tx.commit()
在非托管环境中:
您不必刷新()会话 显式:对commit()的调用 自动触发 同步取决于 会话的FlushMode。打电话给 close()标记会话结束。 close()的主要含义是 JDBC连接将是 会议放弃。这个Java 代码是可移植的,并在两者中运行 非托管和JTA环境。
答案 2 :(得分:0)
如果您使用Eager loading ..将会显示。
对于延迟加载,您需要初始化它:
Parent p = em.find(Parent.class, 1);
Hibernate.initialize(p);
System.out.println(p.child);
有关它的更多信息,请访问here。
答案 3 :(得分:0)
这取决于您为此parent.children集合选择的缓存策略(READ_ONLY,NONSTRICT_READ_WRITE ...)。如果它不是READ_ONLY并且正确完成了子项的持久化,则hibernate将从二级缓存中逐出该集合。