使用FetchType.LAZY

时间:2015-05-19 23:15:19

标签: hibernate jsf jpa lazy-loading

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,我不会得到异常,但我希望数据提取是懒惰的,即仅按需提供。我需要更改什么才能避免此异常?

可能相关

在视图中,当FetchTypeEAGER时成功呈现,我有一个表单为每个父项添加一个子项,一旦添加了一个子项,我尝试使用{ {1}}自动刷新子列表:

f:ajax

但是,刷新失败,因为当我在AJAX上添加子项时,子表没有使用新行更新(我这样做是为了避免重新加载页面),即使相应的数据库事务成功也是如此。当我通过重新加载页面在浏览器中刷新视图时,新添加的子项仅在表中可见。

但请注意,当<h:commandButton value="Add Child" action="#{parentBean.addChild}"> <f:ajax execute="@form" render="childTbl"/> </h:commandButton> LazyInitializationException时,当我第一次尝试加载包含父级及其子级的页面时,会出现FetchType。它与刷新失败没有直接关系,当LAZYFetchType时,会发生刷新失败。但我认为我的代码中可能存在一些根本缺陷,修复后,将启用延迟初始化以及AJAX视图刷新。

1 个答案:

答案 0 :(得分:0)

因为您为childList列定义了FetchType.LAZY获取;看看FetchType.LAZY和FetchType.EAGER与HERE的差异。如果要获取非null的childList对象,则有2个选项:

  1. 将FetchType.LAZY更改为FetchType.EAGER
  2. 当您的Child对象持久调用@Transaction annotationed方法中的getChildren()时。