使用FetchType.LAZY加载子实体时出现LazyInitializationException



当我的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;
<<p> 视图/strong>
<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,我不会得到异常,但我希望数据抓取是懒惰的,即仅按需。我需要做些什么来避免这个异常?

可能相关

在视图中,当FetchTypeEAGER时,它确实成功呈现,我有一个为每个父添加子的表单,一旦添加了子,我尝试使用f:ajax来自动刷新子列表表:

<h:commandButton value="Add Child" action="#{parentBean.addChild}">
    <f:ajax execute="@form" render="childTbl"/>
</h:commandButton>

但是,刷新失败,因为当我在AJAX上添加子表时(我这样做是为了避免重新加载页面),子表没有更新新行,即使相应的DB事务成功。只有当我通过重新加载页面刷新浏览器中的视图时,新添加的子元素才在表中可见。

然而,请注意,当FetchTypeLAZY时,当我第一次尝试加载带有父级及其子级的页面时,LazyInitializationException会发生。这与刷新失败没有直接关系,刷新失败发生在FetchTypeEAGER时。但我认为我的代码中可能存在一些基本缺陷,修复后,将启用延迟初始化和AJAX视图刷新。

因为你定义了FetchType。惰性抓取childList列;看一下FetchType。LAZY和FetchType。热切的差异从这里。如果你想获得不为空的childList对象,有两个选项:

  1. FetchType变化。LAZY to FetchType。希望
  2. 当你的子对象持久化调用getChildren()在@Transaction注释方法。

相关内容

  • 没有找到相关文章

最新更新