Hello,
I'm evaluating Hibernate for JPA, and I've encounted the following symptom. I was hoping someone might shed some light on this:
I created the following remote business method:
Code:
getParentByChildId(Long childId) {
Child c = em.find(Child.class, childId);
Parent p = c.getParent();
System.out.println(p.getClass().toString()); // output: some proxy CGLIB class
return p;
}
The 'parent' property of the Child class is lazy-loaded, but the Parent entity itself has some props which are not lazy, like 'id' and 'name'. The client tries to output the returned parent's name (p.getName()) and gets a LazyInitializationException: no session or invalid session.
Note that when the server code above returns the parent, it actually returns a PROXY for it because Parent does has some lazy props like 'children' which is a OneToMany prop.
Code:
@Entity
public class Parent implements Serializable {
public Parent() {}
@Id @GeneratedValue
private Long id;
public Long getId() { return this.id; }
public void setId(Long id) { this.id = id; }
@OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.REMOVE, mappedBy="parent")
private Collection<Child> children;
public Collection<Child> getChildren() { return children; }
public void setChildren(Collection<Child> children) { this.children = children; }
@Column(name="parent_name")
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override public int hashCode() { ... }
@Override public boolean equals(Object object) { ... }
}
@Entity
public class Child implements Serializable {
public Child() {}
@Id @GeneratedValue
private Long id;
public Long getId() { return this.id; }
public void setId(Long id) { this.id = id; }
@Column(name="child_name")
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@ManyToOne(fetch=FetchType.LAZY, optional=false)
@JoinColumn(name = "parent_id", nullable = false)
private Parent parent;
public Parent getParent() { return this.parent; }
public void setParent(Parent parent) { this.parent = parent; }
@Override public int hashCode() { ... }
@Override public boolean equals(Object object) { ... }
}
I would expect that, when hibernate
serializes an entity with non-lazy props such as Parent, that object could leave the persistence context scope, i.e. become detached, with all of those non-lazy props. For comparison, TopLink impl does not have this issue.
The EJB 3.0 spec defines "detached entities" like so:
"A detached entity may result from ...[various reasons]...; and from serializing an entity or otherwise passing an entity by value—e.g., to a separate application tier, through a remote interface, etc."
It also states:
"The application may access the available state of available detached entity instances after the persistence
context ends. The available state includes:
• Any persistent field or property not marked fetch=LAZY
• Any persistent field or property that was accessed by the application"
ref:
http://jcp.org/aboutJava/communityproce ... index.html
Can someone advise on how to get rid of this exception and why it occurs?
thanks you.
Hibernate version:
3.2.6.ga
Name and version of the database you are using:
mysql 5.0.1