spring – 无法让OpenEntityManagerInViewFilter在JBoss 6.1中运行
作者:互联网
我正在尝试将open-session-in-view行为添加到现有的纯JPA应用程序中.在服务层中使用Spring不是一种选择.我想在Spring的OpenEntityManagerInViewFilter中包装视图,而不必修改EJB层.
我没有运气让OpenEntityManagerInViewFilter(Spring 3.2.2)在JBoss 6.1中工作.绝对会调用过滤器,但我仍然在视图中收到LazyInitializationException.
过滤器和会话bean使用EntityManager的不同实例(和类).过滤器获取org.hibernate.ejb.EntityManagerImpl,而session-bean获取org.jboss.jpa.tx.TransactionScopedEntityManager.我不确定Spring配置对此负责.
这是相关的代码/配置:
战争/ WEB-INF /班/ 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);
}
}
战争/ 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>
战争/ 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会对你有用.它将实体管理器绑定到当前线程,以便spring的事务管理代码可以重用它.问题是spring不处理服务bean的事务管理,因为它由应用程序服务器处理.应用程序服务器没有检测到弹簧绑定到该线程的实体管理器并创建另一个;导致2个不同的实例.
为了使它工作,您应该在spring中定义服务bean,以便spring处理事务管理或使用jboss seam(JBoss Seam: How to Open jpa/hibernate session in view)
标签:spring,jpa,hibernate,jboss6-x,open-session-in-view 来源: https://codeday.me/bug/20190625/1284599.html