2014-11-06 39 views
3

我的应用程序使用Struts2(mvc),Spring(依赖注入),JPA with Hibernate,JUnit以及struts2 -junit插件和struts2弹簧插件。保持会话在JUnit/JPA/Hibernate/Struts和Spring集成测试中打开 - 没有会话或会话关闭 - LazyInitialization异常

这里是我的测试类:

@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; 
       } 
      } 
     } 
     ... 
     ... 
    } 
} 

用户和UDetails都是实体。 UDetalis为ManyToManyUser和Lazily提取。所有实体都被注释。

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上下文类型,实体可以在事务外运行。但是,我不能修改上面的代码并永久保留它。所以我需要删除它。

所以我想,我有这些选项,但不知道如果这些都是可行的,如何:

  1. 获得从Spring应用程序上下文的持久化上下文和传递参数。不确定这是否相关且可能。

  2. 从应用程序上下文获取会话/实体管理器并添加另一层事务。以这种方式,会话运行在两个事务中。一个是从我的测试代码开始,另一个是现有的代码,它会自动关闭,而我的测试代码完成执行之前,我的代码仍处于打开状态。

对于第二个,我尝试使用@Transactional注释该方法。但那并不奏效。不知道为什么。

任何帮助?

更新

样子,Struts的JUnit的插件不加载/读取web.xml中,它具有OpenEntityManagerInViewFilter。所以它没有被加载。

任何其他解决方法或设置此过滤器?

+0

您可以发布测试类的完整代码,或者至少是类定义以及在类级应用的任何注释吗? – 2014-11-06 16:22:16

+0

@AlanHay更新了我的测试课程。请检查。 – 2014-11-06 16:25:48

+0

您正在运行容器测试,因此In不会期望Filter会触发。如果一切都配置正确,我会希望外部交易(在测试方法上)保持活跃并允许实体保持“附加”。我看到你在这里看到了接受的答案。你有没有试过这个解决方案http://stackoverflow.com/a/19109838/1356423 – 2014-11-07 10:35:12

回答

1

如果它对任何人有帮助,我都无法使@Transaction正常工作。但我把这个:

@PersistenceContext(type=PersistenaceContextType.EXTENDED) 

它现在的作品!

+1

嗨。同样的问题在这里,但我使用Spring Data JPA。如何使它与JpaRepository一起工作? – 2015-03-26 13:28:01

相关问题