考虑到Web应用程序中的以下情况:
// EntityManager em, one per Request with Spring's OpenEntityManagerInViewFilter
// Parent oldParent, from previous request (and therefore another persistence context)
Parent parent = em.find(Parent.class, oldParent.getId());
List<Child> children = parent.getChildren(); // Mapped collection with LazyLoading
for (Child child : children) {
...
列表迭代器的调用会导致LazyInitializationException
。这是令人困惑的,因为获取子列表发生在相同的持久化上下文中(或者我错了吗?)。
但是,使用merge()
,它可以正常工作。好像两个请求共享一个持久化上下文。
Parent parent = em.merge(oldParent);
List<Child> children = parent.getChildren();
for (Child child : children) {
...
// No Exception!!
我的推理错误是什么?
加成
我已经证明错误不是由parent.getId()
引起的。这是stacktrace的一部分:
at org.hibernate.collection.PersistentList.iterator(PersistentList.java:138)
这意味着它实际上是导致问题的迭代器。而且它变得更加奇怪 - 我在第一种情况下检查了它(使用find()
),hibernate发出了一个select语句来从数据库中检索新对象,而不是从持久化上下文的缓存中检索。
Addition2
这里有更多的堆栈跟踪:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: edeka.sw.phb.model.Chapter.subChapters, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
at org.hibernate.collection.PersistentList.iterator(PersistentList.java:138)
at java.util.Collections$UnmodifiableCollection$1.<init>(Collections.java:1022)
at java.util.Collections$UnmodifiableCollection.iterator(Collections.java:1021)
//... followed by the line of the foreach.
答案 0 :(得分:0)
我认为您的问题不在迭代部分,因为您使用新近加载的父级进行迭代。 问题必须是.getId()似乎没有加载,然后合并工作,因为不要调用.getId()