JSF2 + Spring3和hibernate:Spring Managed Bean(@Scope value =“view”)LazyInitializationException异常

时间:2012-11-07 00:29:12

标签: spring hibernate jsf-2

我使用找到的in this link代码创建了自定义弹簧作用域,它允许使用类似于JSF2 @ViewScoped的view作用域的Spring托管bean。

当用户按下“提交”按钮时,会发生以下情况:

- Backbean AA (@Scope(value="view") calls injected @Service BB
- @Service BB calls DAO class CC 
- CC is @Transactional(readOnly = true) and has sessionFactory injected 
     private SessionFactory sessionFactory;

    //inject sessionGactory
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
- in CC i set the @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
  for functions such as save/delete/saveOrUpdate

关于这个类的Hibernate映射是:

RegUser.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.testApp.hibernate.RegUser" table="reg_users" schema="dbo" catalog="devDB">
        <id name="userPk" type="java.lang.Long">
            <column name="userPK" />
            <generator class="identity" />
        </id>
        <property name="firstname" type="java.lang.String">
            <column name="firstname" length="25" not-null="true" />
        </property>
        <property name="lastname" type="java.lang.String">
            <column name="lastname" length="50" not-null="true" />
        </property>
        <set name="UserVsOrderses" inverse="true">
            <key>
                <column name="userPK" not-null="true" />
            </key>
            <one-to-many class="com.testApp.hibernate.UserVsOrders" />
        </set>
    </class>
</hibernate-mapping>

UserVsOrders.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.testApp.hibernate.custOrders" table="custOrders" schema="dbo" catalog="devDB">
        <composite-id name="id" class="com.testApp.hibernate.custOrdersId">
            <key-property name="userPk" type="java.lang.Long">
                <column name="userPK" />
            </key-property>
            <key-property name="OrderPk" type="java.lang.Long">
                <column name="OrderPK" />
            </key-property>
        </composite-id>
        <many-to-one name="RegUser" class="com.testApp.hibernate.RegUser" update="false" insert="false" fetch="select">
            <column name="userPK" not-null="true" />
        </many-to-one>
        <many-to-one name="Order" class="com.testApp.hibernate.Order" update="false" insert="false" fetch="select">
            <column name="OrderPK" not-null="true" />
        </many-to-one>
    </class>
</hibernate-mapping>

的applicationContext.xml

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

    <context:component-scan base-package="com.testApp" />
    <context:annotation-config />

    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="view">
                    <bean class="com.testApp.util.ViewScope" />
                </entry>
            </map>
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver">
        </property>
        <property name="url" value="jdbc:jtds:sqlserver://localhost:1433/devDB">
        </property>
        <property name="username" value="blabla"></property>
        <property name="password" value="blabla"></property>
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.c3p0.min_size">5</prop>
                <prop key="hibernate.c3p0.max_size">20</prop>
                <prop key="hibernate.c3p0.idle_test_period">300</prop>
                <prop key="hibernate.c3p0.timeout">1800</prop>
                <prop key="hibernate.c3p0.max_statements">50</prop>
                <prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
                <prop key="c3p0.acquire_increment">1</prop>
            <props>
        </property>


    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager"
        p:sessionFactory-ref="sessionFactory" />

    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

    ...
    <!-- some other beans declared below -->

    ...
    <!-- all the Mapping Resource  -->
</beans>

我的问题是,第一个表单提交一切都很好,但在下一个表单提交我得到:

failed to lazily initialize a collection, no session or session was closed

viewId=/page/regNewCust.xhtml
location=C:\repo\dev\WebRoot\nz\regNewCust.xhtml
phaseId=PROCESS_VALIDATIONS(3)

Caused by:
org.hibernate.LazyInitializationException - failed to lazily initialize a collection, no session or session was closed
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:394)

如果我将bean范围设置为@Scope(value='request')

,页面工作正常

我已尝试将后续内容添加到web.xml,但它没有帮助:

<filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>openSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

我也尝试添加<set name="UserVsOrderses" inverse="true" fetch="join">,但这也无济于事。

任何人都可以指出我做错了什么以及如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

在这里找到解决方案:

Stackoverflow link

我需要添加

<f:attribute name="collectionType" value="java.util.HashSet" />

到所有<h:selectManyListbox&gt;