2011-08-02 5 views
5

컨트롤러 중 하나에서 지연로드 문제가 발생하는 경우가 있습니다. 참고 : OpenSessionInViewInterceptor를 사용하고 있으며 "서비스"계층에 트랜잭션으로 주석을 추가하고 있습니다.봄 + 최대 절전 모드 지연로드 오류

하나의 키와 하나의 SSN을 사용하여 Person 개체를로드하는 여러 가지 방법이 있습니다. 내 사람의 객체에는 느슨하게로드되는 역할 모음이 있습니다. 키로로드 할 때 예상대로 목록에 액세스 할 수 있습니다. SSN으로로드 할 때 목록에 액세스 할 수 없습니다. 내 서비스 계층 구성 파일에서

는 내가 추가 한 : 여기

<tx:annotation-driven /> 

주요 & SSN에 의해 ​​사람을 (나는 이것이 DAO/구조 조정에 있어야 알고로드 내 서비스 계층 작품이다 -이 상속 코드 참조) - SSN 조각의 어느 버전을 참고는 로딩을 할 수 있습니다 - 모두 동일한 클래스에있는 내 컨트롤러에서

@Transactional(readOnly = true, propagation = Propagation.REQUIRED) 
public Person loadPersonByKey(final Person.Key personKey) { 
    Assert.notNull(personKey); 
    return (Person) getHibernateTemplate().get(Person.class, personKey); 
} 

@Transactional(readOnly = true, propagation = Propagation.REQUIRED) 
public Person findPersonBySsn(final SocialSecurityNumber ssn) { 

    @SuppressWarnings("unchecked") 
    //List<Person> results = getHibernateTemplate().findByNamedParam("from core.model.entities.Person as person where ssn = :ssn", "ssn", ssn); 

    Criteria crit = getSession().createCriteria(Person.class); 
    crit.add(Restrictions.eq("ssn", ssn)); 
    List<Person> results = crit.list(); 

    int size = results.size(); 

    Person returnPerson = ((size != 0) ? (Person) results.get(0) : null); 
    return returnPerson; 
} 

유일한 차이점은 키 하나 개를로드 및 SSN 하나로드입니다. 여기에 스택 트레이스의 관련 부분입니다 : 내가 바로 SSN에 의해 ​​로딩 후 키에 의해 사람을로드하는 경우

SEVERE: Servlet.service() for servlet springmvc threw exception 
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: core.model.entities.Person.memberships, no session or session was closed 
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383) 
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375) 
at org.hibernate.collection.AbstractPersistentCollection.readElementByIndex(AbstractPersistentCollection.java:176) 
at org.hibernate.collection.PersistentMap.get(PersistentMap.java:169) 
at core.model.entities.Person.getMemberships(Person.java:870) 
at core.springmvc.controllers.find.FindController.defaultAction(FindController.java:164) 

이상한 메모, 나는 문제없이 컬렉션을 읽을 수 있어요.

편집 : 여기

이 스택 트레이스 이전 로그입니다

2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils CV#905cde28-e60c-4331 P#75004 - Resetting read-only flag of JDBC Connection [Transaction-aware proxy for target Connection [jdbc:oracle:thin:@(description=(address_list=(address=(host=127.0.0.1)(protocol=tcp)(port=11523))(load_balance=yes)(failover=yes))), UserName=USER_NAME, Oracle JDBC driver]] 
2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.hibernate.impl.SessionImpl CV#905cde28-e60c-4331 P#75004 - disconnecting session 
2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.hibernate.jdbc.ConnectionManager CV#905cde28-e60c-4331 P#75004 - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)] 
2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils CV#905cde28-e60c-4331 P#75004 - Returning JDBC Connection to DataSource 
2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.hibernate.jdbc.ConnectionManager CV#905cde28-e60c-4331 P#75004 - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources! 
+0

또한 Hibernate.initialize (person)를 호출하면 초기화 예외가 발생합니다. 서비스 계층에서도 초기화 예외가 발생합니다. – Scott

답변

2

당신은 예외가 어디에서 오는 볼 수있는 스택 추적을 충분히 보여주지 않았다,하지만 난 그게에서의 가정 뷰 레이어. 이것이 뷰 패턴의 열린 세션에 관한 것입니다. 당신은 OpenSessionInViewInterceptor를 사용하고 있다고 말하지만, 분명히 넓은 범위를 제공하지는 못합니다. 인터셉터는 메소드 호출에 적용됩니다. 나는 당신이 당신의 "서비스"에 그것을 적용했다고 추측 할 것입니다. 그렇다면, 그냥 끄는 것도 좋습니다. 그것은 당신을 위해 아무것도하지 않습니다. 패턴의 전체적인 요점은 세션이 열린 상태로 을 넘어 서비스 레이어 경계인을 보장하는 것입니다. 일반적인 웹 애플리케이션의 경우 OpenSessionInViewFilter이 적절한 선택입니다.

+0

다음 두 줄의 스택 추적을 추가했습니다. 그것은 분명히 내부에서 일어나지 않습니다. – Scott

+0

@ Scott : 컨트롤러를 "보기"로 그룹화하십시오. OpenSessionInViewInterceptor는 어디에 적용됩니까? –

+0

표준 OpenSessionInViewInterceptor 사용하기. Dispatcher 서블릿을 통해 처리되는 모든 요청에 ​​적용됩니다. 작동중인 컨트롤러 및 작동하지 않는 컨트롤러를 통해 디버깅 할 때 인터셉터가 사용하는 세션이 있음을 알았습니다. lazy가로드 된 콜렉션을 Hibernate가 랩핑하는 Persistent Collections가 디버깅 할 때 세션을 표시하지 않기 때문에, 뭔가 잘못 설정되어야합니다. – Scott

관련 문제