open-session-in-view 動作を既存の純粋な JPA アプリケーションに追加しようとしています。サービス層で Spring を使用することはオプションではありません。ビューを Spring の OpenEntityManagerInViewFilter でラップしたいので、EJB レイヤーを変更する必要はありません。
OpenEntityManagerInViewFilter (Spring 3.2.2) を JBoss 6.1 で動作させることができません。フィルターは確実に呼び出されていますが、ビューでまだ LazyInitializationException が発生しています。
フィルターとセッション Bean は、EntityManager の異なるインスタンス (およびクラス) を使用しています。フィルターは を取得していますがorg.hibernate.ejb.EntityManagerImpl
、セッション Bean は を取得していorg.jboss.jpa.tx.TransactionScopedEntityManager
ます。どのSpring構成がこれに責任があるのか わかりません。
関連するコード/構成は次のとおりです。
戦争/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);
}
}
戦争/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>