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.

4
  • do you refresh your parent entity once you're done with the transaction? Commented May 19, 2015 at 23:21
  • yes, <f:ajax execute="@form" render="childTbl"/> should do that Commented May 19, 2015 at 23:22
  • You can see this answer , the same issue but with jsp page [link] [1] [1]: stackoverflow.com/questions/19047835/… Commented May 20, 2015 at 2: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<Child> 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. Commented May 20, 2015 at 5:48

1 Answer 1

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.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.