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.