복붙노트

[SPRING] JUnit / JPA / Hibernate / Struts 및 Spring 통합 테스트에서 세션 열기 유지 - 세션 또는 세션 종료 없음 - 지연 초기 화 예외

SPRING

JUnit / JPA / Hibernate / Struts 및 Spring 통합 테스트에서 세션 열기 유지 - 세션 또는 세션 종료 없음 - 지연 초기 화 예외

내 응용 프로그램은 Struts2 (mvc), Spring (Dependency Injection), JPA와 Hibernate, JUnit과 struts2-junit plugin 및 struts2 spring plugin을 사용합니다.

여기 내 테스트 수업이 있습니다 :

@RunWith(SpringJUnit4ClassRunner.class)
public class CustomerSearchIntegrationTest extends StrutsSpringTestCase {

    @Test
    @Transactional
    public void testGetActionProxy() throws Exception {

        ActionProxy proxy;
        String result;

        ActionMapping mapping = getActionMapping("userInfo");
        assertNotNull(mapping);

        ..... // Some JUnit init code..

        ActionProxy proxy = getActionProxy("userInfo");
        UserInfo user = (UserInfo) proxy.getAction();
        result = proxy.execute();

        assertEquals("details", result);
        System.out.prinltn("Username:" + user.getFirstName());

    }
}

GetUserInfo

public class UserInfo extends ActionSupport {
     User user; // Entity
     UDetails details; // Entity

     public String getUserDetails() { //Action method
       user = userMgmt.getUser(usrId);
       if (user != null ) {
            for(UDetails det : user.getUDetails()) { // user.getUDetails() there is where exception gets thrown.
                if(det.getStreet().equals(street)){
                    details = det;
                    break;
                }
            }
       }
       ...
       ...
    }
}

User와 UDetails는 엔티티입니다. UDetalis는 ManyToMany이고 User와 Lazily fetched가 있습니다. 모든 엔티티에 주석이 추가됩니다.

UserMgmt

public class UserMgmt {
    public User getUser(String userId) {
        return userDao.getUser(userId);
    }
}

UserDAO

public class UserDAO extends AbstractJPAImpl{

    public User getUser(String userId) {
        User user = (User) getSession().get(User.class, userId);
        return user;
    }
}

AbstractJPAImpl

@Transactional
public abstract class AbstractJPAImpl {

    private EntityManager em;

    @PersistenceContext
    protected void setEntityManager(EntityManager em) {
        this.em = em;
    }

    @Transactional
    protected Session getSession() {
        return (Session) em.getDelegate();
    }

    ....
}

jpaContext.xml

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  // other config stuff
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

모든 구성 / 컨텍스트 파일이 잘로드됩니다. Struts.xml, jpacontext.xml, beans.xml 등이 모두로드됩니다.

하지만 예외가 있습니다.

failed to lazily initialize a collection of role: com.my.data.User.udetails, no session or session was closed

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: 

다음 행에서 :

 for(UDetails det : user.getUDetails())

분명히 UDetails를 느리게로드하려고 시도하면 예외가 발생합니다. 그러나이 응용 프로그램은 AppServer (WebSphere)에 배포 할 때 잘 작동합니다.

나는 무엇을 잘못 할 수 있 었는가? 세션을 어떻게 열어 두어야합니까?

업데이트 : 추가 정보

나는 OpenEntityManagerInViewFilter를 사용하고있다. 내 web.xml 아래

<filter>
    <filter-name>OpenEntityManagerInViewFilter</filter-name>
    <filter-class>
        org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>OpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

최신 정보:

이것은 매개 변수를 아래와 같이 @PersistenceContext 주석에 전달하면 마침내 작동합니다.

@PersistenceContext(type=PersistenceContextType.EXTENDED)

그래서 나는 트랜잭션이 종료되고있는 것으로 추측하지만 EXTENDED 컨텍스트 유형으로 인해 엔티티는 트랜잭션 외부에서 작동 할 수 있습니다. 그러나 위의 코드를 수정하여 영구히 둘 수는 없습니다. 그래서 나는 그것을 제거해야합니다.

그래서 나는이 옵션들을 가지고 있다고 생각하지만, 이것들이 가능하고 어떻게되는지는 확신 할 수 없다 :

두 번째로, @Transactional을 사용하여 메소드에 주석을 달았습니다. 그러나 그것은 효과가 없었습니다. 이유를 모르겠다.

어떤 도움?

최신 정보

Struts-junit plugin은 OpenEntityManagerInViewFilter가있는 web.xml을로드하거나 읽지 않습니다. 그래서로드되지 않았습니다.

이 필터를 둘러싼 다른 작업이나 설정은 무엇입니까?

해결법

  1. ==============================

    1.도움이된다면 @Transaction을 사용할 수 없습니다. 그러나 나는 이것을 넣었다.

    도움이된다면 @Transaction을 사용할 수 없습니다. 그러나 나는 이것을 넣었다.

     @PersistenceContext(type=PersistenaceContextType.EXTENDED)
    

    그리고 지금 작동합니다!

  2. from https://stackoverflow.com/questions/26783852/keeping-the-session-open-in-junit-jpa-hibernate-struts-and-spring-integration-te by cc-by-sa and MIT license