Hibernate version: 3rc1
Mapping documents:
<!-- parent -->
<class lazy="true" name="Parent" table="parent">
<id name="id" />
<property name="name"/>
<set name="children" lazy="true" inverse="false"
cascade="all-delete-orphan" sort="natural">
<key column="parent_id" />
<one-to-many class="Child" />
</set>
</class>
<!-- child -->
<class lazy="true" name="Child" table="child">
<id name="id" />
<property name="name"/>
<many-to-one name="parent" class="Parent"/>
<set name="children" lazy="true" inverse="false"
cascade="all-delete-orphan" sort="natural">
<key column="parent_id" />
<one-to-many class="GrandChild" />
</set>
</class>
<!-- grand child -->
<class lazy="true" name="GrandChild" table="grand_child">
<id name="id" />
<property name="name"/>
<many-to-one name="parent" class="Child" column="parent_id" />
</class>
Code between sessionFactory.openSession() and session.close():
Parent parent = new Parent("parent name", null);
Long id = (Long) session.save(parent);
//close session and open newSession
Child child = new Child("child name", null, null);
GrandChild grandChild = new GrandChild("grand child name", null);
child.addGrandChild(grandChild);
parent.addChild(child);
Parent parent1 = (Parent) newSession.get(Parent.class, id);
//cannot call hibSess.update(parent) because instance with the same id parent1 was loaded already
hibSess.merge(parent); //error!
Full stack trace of any exception that occurs:
when debugging to:
SortedSetType(SetType).instantiate(Object) line: 44
SortedSetType(CollectionType).replace(Object, Object, SessionImplementor, Object, Map) line: 383
TypeFactory.replace(Object[], Object[], Type[], SessionImplementor, Object, Map) line: 353
...
Because SortedSetType(SetType).instantiate(Object) return a new HashSet instead of TreeSet(for this case), a ClassCastException is thrown.
When running this test case with Hibernate 2.1, call method saveOrUpdateCopy(), no exception happens.
I think this is a bug of version 3.
Any sugestion?
P/S: Exception occurs only when merging child.children, not occur for parent.children because parent.children is a blank instance, but child.children is null value.
SortedSetType(CollectionType).replace(Object, Object, SessionImplementor, Object, Map)
Code:
public Object replace(final Object original, final Object target,
final SessionImplementor session, final Object owner, final Map copyCache)
throws HibernateException {
if ( original == null ) return null;
if ( !Hibernate.isInitialized( original ) ) return target;
if ( original == target ) return target; // is this really a Good Thing?
Object result = target == null ? instantiate( original ) : target;
return replaceElements( original, result, owner, copyCache, session );
}