开发者

Why does EntityManager.merge() prevent LazyInitializationException while EntityManager.find() don't?

Given the following situation in a web application:

// 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) {
     ...

The call of the list iterator causes a LazyInitializationException. This is confusing, because the fetching of the list of children occurs in the same persistence context (or am i wrong?). But, using merge(), it works. As if two request are sharing one persistence context.

Parent parent = em.merge(oldParent);
List<Child> children = parent.getChildren();
for (Child child : children) {
     ...
// No Exception!!

What is my error in reasoning?

Addition

I've proven that the error is not caused b开发者_如何转开发y parent.getId(). This is part of the stacktrace:

at org.hibernate.collection.PersistentList.iterator(PersistentList.java:138)

That means it is actually the iterator that causes the problem. And it's getting even more weird - I've checked that in the first case (with find()), a select statement is issued by hibernate to retrieve a new object from the database, not from the cache of the persistence context.

Addition2

Here's a bit more stacktrace:

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.


I think that your problem is not in the iterating part because you iterate with the new recently loaded parent. The problem has to be with the .getId() that seems to not be loaded then the merge works because dont call the .getId()

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜