我知道实体在发送到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>