0

I am getting a LazyInitializationException when my JSF view requests a list of children for an entity. I am not using Hibernate directly but JPA. The CHILD DB table does have a FK on the PARENT table. It is a very standard relationship.

Here is what the relevant code excerpts look like:

Parent

@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;
    }

Child

@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;

View

<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>

If I change the FetchType to EAGER, I don't get the exception but I want the data fetching to be lazy, i.e. only on demand. What do I need to change to avoid this exception?

May be related

In the view, which does get successfully rendered when the FetchType is EAGER, I have a form to add a child for each parent and, once a child is added, I try to use f:ajax to refresh the children list table automatically:

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

However, that refresh fails as the child table does not get updated with a new row when I add a child upon AJAX (which I do in order to avoid reloading the page), even though the corresponding DB transaction succeeds. The newly added child is only visible in the table when I refresh the view in the browser by reloading the page.

However, please note that the LazyInitializationException occurs when I first try to load the page with a parent and their children when the FetchType is LAZY. It is not directly related to the refresh failure, which happens when the FetchType is EAGER. But I thought there might be some fundamental flaw in my code that, when fixed, will enable both a lazy initialization as well as the AJAX view refresh.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
amphibient
  • 29,770
  • 54
  • 146
  • 240
  • do you refresh your parent entity once you're done with the transaction? – guilhebl May 19 '15 at 23:21
  • yes, `` should do that – amphibient May 19 '15 at 23:22
  • You can see this answer , the same issue but with jsp page [link] [1] [1]: http://stackoverflow.com/questions/19047835/hibernate-lazyinitializationexception-while-using-collection-in-spring-jsp-page – Abdou Amari May 20 '15 at 02:37
  • This is because you are trying to refer to a lazily initialized collection here in this EL `#{parent.children}`. I assume the EL refers to `private List childList` being returned by `getChildren()` in the `Parent` entity. This has whatsoever nothing to do with JSF. Use a separate query to retrieve a list of children based on its parent row depending upon the functional requirements or project's structure/flow. – Tiny May 20 '15 at 05:48

1 Answers1

0

Because you define FetchType.LAZY fetching for childList column; take a look at FetchType.LAZY and FetchType.EAGER differences from HERE . If you want to get not null childList object, there are 2 options:

  1. Change FetchType.LAZY to FetchType.EAGER
  2. When your Child object persistent call getChildren() inside @Transaction annotationed method.
Community
  • 1
  • 1
dogankadriye
  • 538
  • 3
  • 13