Hi
I've read some threads about LazyInitializationException. However, something I'm still curious about is: Why throwing an exception instead of returning null.
Background for this question:
I've got a recursive object (tree-like structure) containing a parent property.
Code:
<hibernate-mapping package="ch.jfactory.pm.data">
<class name="ch.jfactory.pm.data.modelapi.IFEntry" table="ENTRY">
<id name="id" type="integer" unsaved-value="null">
<generator class="identity"/>
</id>
<discriminator column="discriminator"/>
<property name="text" type="string"/>
<property name="timestamp" type="timestamp"/>
<property name="rank" type="integer"/>
<property name="startDate" type="timestamp"/>
<property name="endDate" type="timestamp"/>
<many-to-one name="parent" class="ch.jfactory.pm.data.modelapi.IFEntry"/>
<many-to-one name="type" class="ch.jfactory.pm.data.model.DefaultType"/>
<many-to-one name="work" class="ch.jfactory.pm.data.model.DefaultWork"/>
<set name="children" inverse="true" order-by="rank asc" cascade="all" >
<key column="PARENT"/>
<one-to-many class="ch.jfactory.pm.data.modelapi.IFEntry"/>
</set>
<subclass name="ch.jfactory.pm.data.model.DefaultEntry"
discriminator-value="default"/>
</class>
</hibernate-mapping>
IFEntry is an interface and I simply want to have one implementing class for it (DefaultEntry). So I have choosen the table-per-class-hierarchy approach. Before I added the subclass element (before I was implementing the interface), the following code worked perfectly:
Code:
public void setParent(IFEntry parent) {
if (this.parent != parent) {
// Set the parent
final IFEntry oldParent = this.parent;
this.parent = parent;
// Make sure the old parent does not contain this entry any more
if (oldParent != null && oldParent.getChildren().contains(this)) {
oldParent.deleteChild(this);
}
// Make sure the parent contains this entry
final Set children = parent.getChildren();
if (parent != null && children != null && !children.contains(this)) {
children.add(this);
}
}
}
Since I started to use the interface and the subclass element, the same code fails to load the children set and I get a LazyInitializationException. Now I am catching this exception and initializing the children objects in the catch block. This is ugly and I would appreciate to have a better solution to it.
I am seduced to believe that returning null instead of throwing an exception would be more user-friendly, at least from the point of view of the above code.
On the other hand I don't understand why switching to the interface is an issue.
The above code is called actually in a session:
Code:
final Session session = HibernateUtils.currentSession();
list = query(session, "IS NULL");
HibernateUtils.closeSession();
Details: Hibernate 2.1.4, HSQLDB 1.7.2rc6
Thanks for any ideas on the backgrounds.