当JSF
视图请求实体的子项列表时,我收到LazyInitializationException
。我没有直接使用Hibernate
,而是JPA
。 CHILD DB表在PARENT表上有一个FK。这是一种非常标准的关系。
以下是相关代码摘录的内容:
父
@Entity
@Table(name="PARENT")
@NamedQueries({@NamedQuery(name = "Parent.getByID",
query = "SELECT i FROM Parent i WHERE i.parentID = :parentID")})
public class Parent implements Serializable {
@Id
@SequenceGenerator(name="PARENT_SEQ_GEN", sequenceName="DB_SEQ", allocationSize = 1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="PARENT_SEQ_GEN")
@Column(name="PARENT_ID")
private long parentID;
/* other stuff */
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", fetch = FetchType.LAZY)
private List<Child> childList;
/* other stuff */
public List<Child> getChildren() {
return this.childList;
}
儿童
@Entity
@Table(name="CHILD")
@NamedQueries({@NamedQuery(name = "Child.getByID",
query = "SELECT i FROM Child i WHERE i.childID = :childID")})
public class Child implements Serializable {
@Id
@SequenceGenerator(name="CHILD_SEQ_GEN", sequenceName="DB_SEQ", allocationSize = 1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CHILD_SEQ_GEN")
@Column(name="CHILD_ID")
private long childID;
@JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID", insertable = true, updatable = false)
@ManyToOne(optional = false)
private Parent parent;
查看
<h:dataTable id="childTbl" value="#{parent.children}"
var="child" width="100%"
styleClass="data" border="1" cellpadding="2"
cellspacing="0">
<h:column>
<f:facet name="header">Child Name</f:facet>
#{child.name}
</h:column>
<h:column>
<f:facet name="header">DOB</f:facet>
#{child.dob}
</h:column>
</h:dataTable>
如果我将FetchType
更改为EAGER
,我不会得到异常,但我希望数据提取是懒惰的,即仅按需提供。我需要更改什么才能避免此异常?
可能相关
在视图中,当FetchType
为EAGER
时成功呈现,我有一个表单为每个父项添加一个子项,一旦添加了一个子项,我尝试使用{ {1}}自动刷新子列表:
f:ajax
但是,刷新失败,因为当我在AJAX上添加子项时,子表没有使用新行更新(我这样做是为了避免重新加载页面),即使相应的数据库事务成功也是如此。当我通过重新加载页面在浏览器中刷新视图时,新添加的子项仅在表中可见。
但请注意,当<h:commandButton value="Add Child" action="#{parentBean.addChild}">
<f:ajax execute="@form" render="childTbl"/>
</h:commandButton>
为LazyInitializationException
时,当我第一次尝试加载包含父级及其子级的页面时,会出现FetchType
。它与刷新失败没有直接关系,当LAZY
为FetchType
时,会发生刷新失败。但我认为我的代码中可能存在一些根本缺陷,修复后,将启用延迟初始化以及AJAX视图刷新。
答案 0 :(得分:0)
因为您为childList列定义了FetchType.LAZY获取;看看FetchType.LAZY和FetchType.EAGER与HERE的差异。如果要获取非null的childList对象,则有2个选项: