I have an object with an array inside (1 to many). I read the object from the DB, close my session, open another session, attach it (either with lock or update) and I get exceptions or it tries to disconnect the array items from the object.
I discussed how web sessions should be handled, and was convinced that the Hibernate session is closed when the user is thinking, so I think I need to do something like this (unless someone has a better idea).
Any advice? thanks in advance!
Hibernate version:
2.1.4
Mapping documents:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping
package="edu.upenn.isc.directory.beans.plsql"
schema="COMADMIN">
<class name="Person" table="member">
<id name="pennId" column="penn_id">
<generator class="assigned"/> <!-- dont auto-id -->
</id>
<array name="comadminAffiliations" cascade="all" >
<key column="penn_id"/>
<index column="affiliation_order"/>
<one-to-many class="edu.upenn.isc.directory.beans.ComadminAffiliationImpl"/>
</array>
</class>
</hibernate-mapping>
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping
package="edu.upenn.isc.directory.beans"
schema="COMADMIN">
<class name="ComadminAffiliationImpl" table="Affiliation_Index">
<composite-id>
<key-property name="pennid" column="penn_id"/>
<key-property name="affiliationCode" column="affiliation_code"/>
</composite-id>
<property name="source"/>
<property name="activeCode" column="active_code"/>
<property name="fullName" column="full_name"/>
<property name="sortName" column="sort_name"/>
<property name="prefix" column="name_prefix" />
<property name="firstName" column="first_name"/>
<property name="middleName" column="middle_name"/>
<property name="lastName" column="last_name"/>
<property name="directoryDescription" column="directory_description"/>
<property name="directoryOrganization" column="directory_organization"/>
<property name="displayPublicFlag" column="display_public_flag"/>
<property name="displayPennFlag" column="display_penn_flag"/>
<property name="displayPrintFlag" column="display_print_flag"/>
<property name="affiliationOrder" column="affiliation_order"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():(Some of this is an API wrapper, if you want the details let me know, though it is probably what you expect)
Code:
HibernateSession hibSession = new HibernateSession("comadminOracle");
Person person = (Person)hibSession.retrieveObject(
Person.class, new Integer(10021368));
//System.out.println(person);
hibSession.endAndCloseSession(HibernateAction.COMMIT);
hibSession = new HibernateSession("comadminOracle");
Session session = hibSession.getSession();
try {
// session.lock(person, LockMode.NONE);
session.update(person);
Transaction transaction = hibSession.getTransaction();
transaction.commit();
session.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.toString());
}
Full stack trace of any exception that occurs:If I run as is, I get an exception from my trigger that says affiliations need to be associated with Person:
Code:
net.sf.hibernate.JDBCException: could not delete collection: [edu.upenn.isc.directory.beans.plsql.Person.comadminAffiliations#10021368]
at net.sf.hibernate.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:496)
at net.sf.hibernate.impl.ScheduledCollectionRemove.execute(ScheduledCollectionRemove.java:22)
...
If I change the update to a lock (since the object is clean), this is what happens:
Code:
net.sf.hibernate.HibernateException: reassociated object has dirty collection reference
at net.sf.hibernate.impl.OnLockVisitor.processCollection(OnLockVisitor.java:68)
at net.sf.hibernate.impl.AbstractVisitor.processValue(AbstractVisitor.java:69)
at net.sf.hibernate.impl.AbstractVisitor.processValues(AbstractVisitor.java:36)
at net.sf.hibernate.impl.AbstractVisitor.process(AbstractVisitor.java:93)
at net.sf.hibernate.impl.SessionImpl.reassociate(SessionImpl.java:1685)
at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1705)
at edu.upenn.isc.directory.Persistence.main(Persistence.java:40)
Name and version of the database you are using:Oracle 9i
Debug level Hibernate log excerpt:Here is some SQL (the first two statements seem fine, but the third tries to delete the reference from the many to the one...)
Code:
1092203275166|0|0|statement|update COMADMIN.Affiliation_Index set source=?, active_code=?, full_name=?, sort_name=?, name_prefix=?, first_name=?, middle_name=?, last_name=?, directory_description=?, directory_organization=?, display_public_flag=?, display_penn_flag=?, display_print_flag=?, affiliation_order=? where penn_id=? and affiliation_code=?|update COMADMIN.Affiliation_Index set source='PENNPAY', active_code='A', full_name='MICHAEL CHRISTOPHER HYZER', sort_name='HYZER, MICHAEL CHRISTOPHER', name_prefix=' ', first_name='MICHAEL', middle_name='CHRISTOPHER', last_name='HYZER', directory_description='', directory_organization='', display_public_flag='D', display_penn_flag='D', display_print_flag='D', affiliation_order=0 where penn_id=10021368 and affiliation_code='STAF'
1092203275213|15|0|statement|update COMADMIN.Affiliation_Index set source=?, active_code=?, full_name=?, sort_name=?, name_prefix=?, first_name=?, middle_name=?, last_name=?, directory_description=?, directory_organization=?, display_public_flag=?, display_penn_flag=?, display_print_flag=?, affiliation_order=? where penn_id=? and affiliation_code=?|update COMADMIN.Affiliation_Index set source='SRS', active_code='I', full_name='MICHAEL C HYZER', sort_name='HYZER, MICHAEL C', name_prefix=' ', first_name='MICHAEL', middle_name='C', last_name='HYZER', directory_description='', directory_organization='', display_public_flag='D', display_penn_flag='D', display_print_flag='D', affiliation_order=1 where penn_id=10021368 and affiliation_code='STU'
1092203275244|15|0|statement|update COMADMIN.Affiliation_Index set penn_id=null, affiliation_order=null where penn_id=?|update COMADMIN.Affiliation_Index set penn_id=null, affiliation_order=null where penn_id=10021368