带有EJB后端的SpringMVC前端中的LazyInitializationException

时间:2014-02-20 15:25:29

标签: java hibernate spring-mvc jboss ejb

我在JBoss AS 7.1.1上有一个EJB应用程序,它使用Hibernate 4.3通过jta-data-source进行数据库连接。我的persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
             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_2_0.xsd">
    <persistence-unit name="primary" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:/postds</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.ProgressDialect" />
            <property name="hibernate.connection.charSet" value="UTF-8" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.show_sql" value="false" />
        </properties>
    </persistence-unit>
</persistence>

我使用像this这样的DAO模式:

@Stateless  
public abstract class GenericHibernateDAO<T, ID extends Serializable>  
        implements GenericDAO<T, ID> {  

    private Class<T> persistentClass;  

    @PersistenceContext  
    private EntityManager em;  

    protected Session getSession() {
        return em.unwrap(Session.class);
    }

    public T save(T entity) {
        getSession().saveOrUpdate(entity);
        return entity;
    }

...  

在EJB后端,所有Lazy-initialized字段都可以正常工作。现在我的后端需要一个小的Web管理面板。我熟悉Spring MVC并决定使用它。在Spring中,MVC使用EJB bean不是问题。但是Lazy-initialized字段在Spring控制器中不起作用,我得到:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

我尝试在web.xml中使用OpenSessionInViewFilter:

    <filter>
        <filter-name>openSessionFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>openSessionFilter</filter-name>
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>

OpenSessionInViewFilter需要sessionFactory bean。我将它的定义添加到applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                           http://www.springframework.org/schema/jee
                           http://www.springframework.org/schema/jee/spring-jee-3.2.xsd">

    <jee:jndi-lookup id="dataSource" jndi-name="java:/postds"/>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

但它没有解决我的问题......你有什么建议吗? 非常感谢!

1 个答案:

答案 0 :(得分:0)

如果您使用EJB容器管理事务和会话。在事务提交之后(默认情况下,所有EJB方法都是事务性的)容器会破坏会话。如果您使用延迟加载,那么您将获得org.hibernate.LazyInitializationException

尝试通过HQL或Criteria API使用fetch join lazy loaded字段。

有关详细信息,请参阅this answer