org.hibernate.LazyInitializationException:懒得初始化一个集合(Spring 4.1.6 + Hibernate 4.1.0)

时间:2015-05-30 19:34:21

标签: spring hibernate jsf jpa

我知道实体在发送到JSF容器时是detached,所以我在web.xml中创建了一个过滤器。过滤器有效,因为我能够调试它,但在下面的代码片段中抛出异常。

来自org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter

的代码段
try {
     filterChain.doFilter(request, response);
}

例外:

15:12:06,259 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (http-/127.0.0.1:8080-5) org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: hh.entity.Address.persons, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:137)
at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:242)
at javax.faces.model.ListDataModel.isRowAvailable(ListDataModel.java:109)
at javax.faces.model.ListDataModel.setRowIndex(ListDataModel.java:184)
at javax.faces.model.ListDataModel.setWrappedData(ListDataModel.java:219)
at javax.faces.model.ListDataModel.<init>(ListDataModel.java:78)
at org.primefaces.component.api.UIData.getDataModel(UIData.java:766)
at javax.faces.component.UIData.getRowCount(UIData.java:356)
at org.primefaces.component.datatable.DataTableRenderer.encodeTbody(DataTableRenderer.java:806)
at org.primefaces.component.datatable.DataTableRenderer.encodeTbody(DataTableRenderer.java:788)
at org.primefaces.component.datatable.DataTableRenderer.encodeRegularTable(DataTableRenderer.java:281)
at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:243)
at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:85)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
...

的web.xml

<filter>
    <filter-name>OpenEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    <init-param>
        <param-name>entityManagerFactoryBeanName</param-name>
        <param-value>entityManagerFactory</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>OpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

的applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/jdbc
                        http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
                        http://www.springframework.org/schema/tx 
                        http://www.springframework.org/schema/tx/spring-tx.xsd
                        http://www.springframework.org/schema/jee 
                        http://www.springframework.org/schema/jee/spring-jee.xsd">
    <!-- Enable Spring Annotation Configuration -->
    <!-- Scan for all of Spring components such as Spring Service -->
    <context:component-scan base-package="hh.*" />

    <jee:jndi-lookup id="dataSource" jndi-name="jboss/datasources/h2home" />

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="homewebPersistence" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- Detect @Transactional -->
    <tx:annotation-driven />
</beans>

的persistence.xml

<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="homewebPersistence" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <class>hh.entity.Person</class>
        <class>hh.entity.Address</class>

        <properties>
            <!-- Properties for Hibernate -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
        </properties>
    </persistence-unit>
</persistence>

Address.java

@Entity
@Table(name = "address")
@AttributeOverride(name="id", column=@Column(name="addressid"))
public class Address extends BaseEntity<Integer> implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name = "street1")
    private String street1;

    // Lazy load this field
    @Column(name = "street2")
    @Basic(fetch=FetchType.LAZY)
    private String street2;

    @Column(name = "city")
    private String city;

    @Column(name = "state")
    private String state;

    @Column(name = "zipcode")
    private String zipCode;

    @OneToMany(fetch=FetchType.LAZY, mappedBy="address")
    private List<Person> persons;

    // getter/setter ommited

}

Person.java

@Entity
@Table(name = "person")
@AttributeOverride(name = "id", column = @Column(name = "personid"))
public class Person extends BaseEntity<Integer> implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name = "firstname")
    private String firstName;

    @Column(name = "middlename")
    private String middleName;

    @Column(name = "lastname")
    private String lastName;

    @Column(name = "userid")
    private String userId;

    @Column(name = "password")
    private String password;

    @Column(name = "branchid")
    private Integer branchId;

    @Column(name = "addressid")
    private Integer addressId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "addressid", insertable = false, updatable = false)
    private Address address;

    // Getter/Setter ommited

}

的index.xhtml

<h:form>
    <p:dataTable var="address" value="#{menuBean.addresses}">
        <p:column style="width:16px">
            <p:rowToggler />
        </p:column>
        <p:column headerText="Id">
            <h:outputText value="#{address.id}" />
        </p:column>
        <p:column headerText="Street1">
            <h:outputText value="#{address.street1}" />
        </p:column>
        <p:rowExpansion>
            <p:dataTable var="person" value="#{address.persons}">
                <p:column headerText="Id">
                    <h:outputText value="#{person.id}" />
                </p:column>
            </p:dataTable>
        </p:rowExpansion>
    </p:dataTable>
</h:form>

0 个答案:

没有答案