2011-03-17 5 views
3

오류는 failed to lazily initialize a collection, no session or session was closed입니다.지연 가져 오기에서 세션 된 오류 발생

거의 같은 질문을하는 사람들이 많이 있지만, 그 해결책은 그리 직관적이지 않습니다. 그리고, 나는 이상한 오류 메시지가 설명하는 또 다른 질문을 게시하는 것이 필요하다고 생각 : (. 너무 오래이기 때문에 여기에 소스 코드를 붙여 않을거야)

DEBUG [main] (AbstractPlatformTransactionManager.java:365) - Creating new transaction with name [com.bee32.plover.orm.feaCat.FeaturePlayer.tcList]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
DEBUG [main] (HibernateTransactionManager.java:493) - Opened new Session [[email protected]] for Hibernate transaction 
DEBUG [main] (HibernateTransactionManager.java:523) - Not preparing JDBC Connection of Hibernate Session [[email protected]] 
DEBUG [main] (HibernateTemplate.java:397) - Found thread-bound Session for HibernateTemplate 
Hibernate: /* criteria query */ select 
    ... 

ERROR [main] (LazyInitializationException.java:42) - failed to lazily initialize a collection, no session or session was closed 
org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380) 
    ... 
    at java.util.HashSet.<init>(HashSet.java:116) 
    ... 
    at org.hibernate.loader.Loader.list(Loader.java:2124) 
    ... 
    at org.springframework.orm.hibernate3.HibernateTemplate$5.doInHibernate(HibernateTemplate.java:590) 
    ... 

DEBUG [main] (HibernateTemplate.java:422) - Not closing pre-bound Hibernate Session after HibernateTemplate 
DEBUG [main] (AbstractPlatformTransactionManager.java:843) - Initiating transaction rollback 
DEBUG [main] (HibernateTransactionManager.java:672) - Rolling back Hibernate transaction on Session [[email protected]] 
DEBUG [main] (HibernateTransactionManager.java:734) - Closing Hibernate Session [[email protected]] after transaction 

알 수 있듯이 lazy-fetch가 trigged 될 때 오류가 발생했으며 이미 스레드 바운드 세션이 있으며 트랜잭션이 롤백 될 때까지 아직 닫히지 않았습니다.

그럼 왜 no session or session was closed이보고 되나요?

편집 관련 출처 : 엔티티가 세션 및 수집을로드 할 수 게으른에서 분리 될 수

@Transactional 
public void tcList() { 
    for (Cat cat : dao.list()) { 
     System.out.println("Saved cat: " + cat); 
    } 
} 
+0

JUnit 테스트 케이스에서 실행 중이십니까? –

답변

2

스레드에 바인드 된 세션이 있지만이 세션에서 관리하는 catList인지 여부는 무엇입니까? 이 세션은 상용구 코드를 처리하는 hibernate 템플릿에 의해 dao.list() 내부에서 종료되었을 수 있습니다.

문제를 해결하는 한 가지 방법은 목록을 반환하기 전에 dao.list() 함수 내에서 list.get (0) .someGetter()를 호출하는 것입니다. 이렇게하면 실제 값으로 목록이 채워지며 지연 초기화 예외가 발생하지 않아야합니다. 고양이가 게으른 초기화 된 추가 객체들로 구성되어 있다면, 그 속성들을 사용하기를 원한다면 getter 속성을 호출해야합니다.

또한 dao.list() 메소드 (있는 경우)에 Transactional 주석을 제거해보십시오. Propagation_Required 특성을 사용하는 대신 호출하는 함수에서 만든 트랜잭션을 사용하십시오. dao.list()에서 @Transactional을 사용한 경우 트랜잭션 관리자는이 함수에서 return 할 때 transaction.commit()/session.close()를 트리거 할 수 있으므로 catList는 분리 된 엔터티가됩니다.이 경우 모든 cat은 여전히 프록시.

0

그냥 프록시? 그것을 사용하고 싶다면 세션에 병합해야합니까?

+0

병합은 비용이 많이 드는 작업입니다. – BDR

0

이것은 세션에서 콜렉션을로드/초기화하려고한다는 것을 의미합니다. 아마도 당신은 U 세션을 끝낼 때까지 세션을 유지해야합니다 ..... ..... 세션 코드를 사용하여 세션 리소스를 관리해야 함을 의미합니다 ... ppl은 엔티티의 set 메소드에서 lazy 콜렉션을 초기화 할 것을 제안합니다. 열정적 인 가져 오기 세션과 같은 게으른 가져 오기를 사용하는 것이 가장 좋은 방법 일 수 있습니다. ...

관련 문제