2010-12-01 2 views
2

웹 응용 프로그램에서 다음과 같은 상황이 발생했습니다.EntityManager.merge()가 LazyInitializationException을 방지하는 이유는 무엇입니까?

// 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 문을 실행했는지 확인했습니다.

추가 2
다음은 스택 추적입니다.

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

:

Addition2
다음은 좀 더 스택 트레이스입니다. 문제는 .getId()가로드되지 않는 것 같습니다. 그러면 .getId()를 호출하지 않기 때문에 병합이 작동합니다.

+0

감사합니다. lujop하지만이 경우는 아닙니다. 'parent.getId()'를 통해 성공적으로 ID를 얻을 수 있지만 반복이 실패합니다. 내 편집 내용을 확인하십시오. – Zeemee

+0

매우 이상합니다. 자세한 스택 추적을 넣을 수 있습니까? 그리고 코드는 정확히 당신이 넣었거나 단순화 한 것입니까? – lujop

+0

stacktrace를 더 추가했습니다. 나는 약간의 코드를 단순화 시켰지만, 그것은 중요하지 않아야한다. – Zeemee

관련 문제