gpt4 book ai didi

spring - 无法让 OpenEntityManagerInViewFilter 在 JBoss 6.1 中工作

转载 作者:行者123 更新时间:2023-12-02 02:12:55 24 4
gpt4 key购买 nike

我正在尝试将打开 session View 行为添加到现有的纯 JPA 应用程序。在服务层使用 Spring 不是一个选择。我想将 View 包装在 Spring 的 OpenEntityManagerInViewFilter 中,而不必修改 EJB 层。

我没有运气让 OpenEntityManagerInViewFilter (Spring 3.2.2) 在 JBoss 6.1 中工作。过滤器肯定被调用,但我仍然在 View 中收到 LazyInitializationException。

过滤器和 session bean 使用 EntityManager 的不同实例(和类)。过滤器获取 org.hibernate.ejb.EntityManagerImpl ,而 session bean 获取 org.jboss.jpa.tx.TransactionScopedEntityManager 。我不确定 Spring 配置是造成这种情况的。

这是相关的代码/配置:

war/WEB-INF/classes/test.web.servlet.TestServlet

public class TestServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

@EJB
private ServiceLocal service;

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

long parentId = Long.parseLong(req.getParameter("parentId"));
Parent parent = service.retrieveParent(parentId);

// this call throws a LazyInitializationException
// because parent.children.session is NULL
parent.getChildren().iterator().next().getName();

req.setAttribute("parent", parent);
RequestDispatcher requestDispatcher = this.getServletContext().getRequestDispatcher("/WEB-INF/jsp/view.jsp");
requestDispatcher.forward(req, resp);
}
}

ejb/test.ejb.session.ServiceBean

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ServiceBean implements ServiceLocal, Service {

@PersistenceContext(name="test")
private EntityManager entityManager;

@Override
public Parent retrieveParent(Long parentId) {
return entityManager.find(Parent.class, parentId);
}
}

war/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">

<display-name>test-war</display-name>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring.xml</param-value>
</context-param>

<filter>
<filter-name>osiv-filter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>

<servlet>
<servlet-name>test-servlet</servlet-name>
<servlet-class>test.web.servlet.TestServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>test-servlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

<filter-mapping>
<filter-name>osiv-filter</filter-name>
<servlet-name>test-servlet</servlet-name>
</filter-mapping>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

</web-app>

war/WEB-INF/spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="persistenceUnitName" value="test" />
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.JBossTransactionManagerLookup
</prop>
</props>
</property>
</bean>
</beans>

ejb/META-INF/persistence.xml

<persistence
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="test" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MSSQLDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.use_sql_comments" value="true" />
<property name="jboss.entity.manager.factory.jndi.name" value="java:/testEntityManagerFactory" />
<property name="jboss.entity.manager.jndi.name" value="java:/testEntityManager" />
</properties>
</persistence-unit>
</persistence>

最佳答案

我认为没有必要使用自定义 EntityManagerFactory 通过 JDNI 查找 EntityManagerFactory,该元素应该处理这一点。

我对你的设置进行了更多的考虑,我认为 spring OpenEntityManagerInViewFilter 不会为你工作。它将一个实体管理器绑定(bind)到当前线程,以便spring的事务管理代码可以重用它。问题是 spring 不处理服务 bean 的事务管理,因为这是由应用程序服务器处理的。应用服务器没有检测到Spring绑定(bind)到线程的实体管理器,并创建了另一个;导致 2 个不同的实例。

要使其工作,您应该在 spring 中定义服务 bean,以便 spring 处理事务管理,或者使用 jboss seam ( JBoss Seam: How to Open jpa/hibernate session in view )

关于spring - 无法让 OpenEntityManagerInViewFilter 在 JBoss 6.1 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16281675/

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