gpt4 book ai didi

java - 在 JUnit/JPA/Hibernate/Struts 和 Spring 集成测试中保持 session 打开 - 无 session 或 session 关闭 - LazyInitialization 异常

转载 作者:行者123 更新时间:2023-12-02 03:38:13 26 4
gpt4 key购买 nike

我的应用程序使用 Struts2(mvc)、Spring(依赖注入(inject))、带有 Hibernate 的 JPA、JUnit 以及 struts2-junit 插件和 struts2 spring 插件。

这是我的测试类:

@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());

}
}

获取用户信息

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 是带有 UserManyToMany 并延迟获取。所有实体都带有注释。

用户管理

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

用户DAO

public class UserDAO extends AbstractJPAImpl{

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

抽象JPAImpl

@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等都已加载。

但我遇到了一个异常(exception):

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) 中时,该应用程序可以正常工作。

我可能做错了什么?如何保持 session 开放?

更新:更多信息

我正在使用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)

所以我猜,事务正在关闭,但由于扩展上下文类型,实体可以在事务之外操作。但是,我无法像上面那样修改代码并永久保留它。所以我需要删除它。

所以我想,我有这些选择,但不确定这些是否可行以及如何实现:

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

  2. 从应用程序上下文中获取 session /实体管理器并添加另一层事务。这样, session 就可以在两个事务中运行。一个是从我的测试代码开始的,另一个是在现有代码中,它会自动关闭,而我的则保持打开状态,直到我的测试代码完成执行。

对于第二个,我尝试使用 @Transactional 注释该方法。但这没有用。不知道为什么。

有什么帮助吗?

更新

看起来,struts-junit 插件不会加载/读取具有 OpenEntityManagerInViewFilter 的 web.xml。所以它没有被加载。

还有其他解决办法或设置此过滤器吗?

最佳答案

如果它对任何人有帮助,我无法让@Transaction 工作。但我这样说:

 @PersistenceContext(type=PersistenceContextType.EXTENDED)

现在可以使用了!

......

关于java - 在 JUnit/JPA/Hibernate/Struts 和 Spring 集成测试中保持 session 打开 - 无 session 或 session 关闭 - LazyInitialization 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26783852/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com