I get a referential integrity error when I try to delete an object that is also referred to in a many-to-many list mapping. Not sure what I'm doing wrong here.
I have one class of object, Incident which I store in another object, IncidentTracker. Incidents are stored in a list in IncidentTracker.
That works fine. I can add incoming Incidents to IncidentTracker and they show up in IncidentTracker's map table.
But when another component or whatever tries to delete() and Incident that is also being referenced by IncidentTracker's mapping table, a referential integrity error gets thrown.
I need to be able to delete the incident without explicitly telling IncidentTracker to delete it from it's list first (this is in an ejb environment, the incidentracker does get a jms event saying that the incident is being deleted, but that event is asynchronous and thus the source of the event may have already tried to delete the Incident).
Code:
<list name="incidents" table="incident_tracker_maps" lazy="false"
inverse="false" cascade="all-delete-orphan">
<key >
<column name="incident_tracker_id" sql-type="char(36)" />
</key>
<index column="list_index"/>
<many-to-many class="com.mycompany.incident.Incident" outer-join="auto">
<column name="incident_id" sql-type="char(36)"/>
</many-to-many>
</list>
The delete call is being handled by Springframework's hibernate templates, so I do not think flushing etc is the problem.
Also I tried to make the mapping bidirectional, putting it in Incident too with the same mapping table name and inverse set to true, but that threw some other exception that made no sense. Also I do not wish for the inicdent object to have to know anything at all about the Tracker object.
The object mapping is essentially as follows (I have cut out a lot of superfluous properties etc and renamed things a little, also the mapping is generated by xdoclet, so that is why the formatting is goofy):
Code:
<class
name="com.mycompany.event.Occurrence"
table="occurrences"
dynamic-update="false"
dynamic-insert="false" >
<id name="id" type="com.mycompany.framework.hibernate.UUIDType" >
<column
name="occurrence_id"
sql-type="char(36)"
/>
<generator class="com.mycompany.framework.hibernate.UUIDGenerator">
</generator>
</id>
<joined-subclass
name="com.mycompany.incident.Incident"
table="incidents"
dynamic-update="false"
dynamic-insert="false">
<key>
<column
name="incident_id"
sql-type="char(36)"
/>
</key>
</joined-subclass>
</class>
<class
name="com.mycompany.model.ModelObject"
table="objects"
dynamic-update="false"
dynamic-insert="false" >
<id
name="id"
type="com.mycompany.framework.hibernate.UUIDType" >
<column
name="object_id"
sql-type="char(36)"
/>
<generator class="com.mycompany.framework.hibernate.UUIDGenerator">
</generator>
</id>
<joined-subclass
name="com.mycompany.model.SomeModel"
table="devices"
dynamic-update="false"
dynamic-insert="false" >
<key >
<column
name="some_model_id"
sql-type="char(36)"
/>
</key>
<joined-subclass
name="com.mycompany.IncidentTracker"
table=incident_tracker"
dynamic-update="false"
dynamic-insert="false" >
<key >
<column
name="incident_tracker_id"
sql-type="char(36)"
/>
</key>
<list
name="incidents"
table="incident_tracker_maps"
lazy="false"
inverse="false"
cascade="all-delete-orphan">
<key >
<column
name="incident_tracker_id"
sql-type="char(36)"
/>
</key>
<index
column="list_index"
/>
<many-to-many
class="com.mycompany.incident.Incident"
outer-join="auto">
<column
name="incident_id"
sql-type="char(36)"
/>
</many-to-many>
</list>
</joined-subclass>
</joined-subclass>
</class>
Code:
10:56:18,975 ERROR [LogInterceptor] RuntimeException:
org.springframework.jdbc.UncategorizedSQLException: (SessionSynchronization): encountered SQLException [ERROR: fkf6b4db9257bb23a8 referential integrity violation - key in incidents still referenced from incident_tracker_maps
]; nested exception is java.sql.SQLException: ERROR: fkf6b4db9257bb23a8 referential integrity violation - key in incidents still referenced from incident_tracker_maps
java.sql.SQLException: ERROR: fkf6b4db9257bb23a8 referential integrity violation - key in incidents still referenced from incident_tracker_maps
at org.postgresql.core.QueryExecutor.execute(QueryExecutor.java:131)
at org.postgresql.jdbc1.AbstractJdbc1Connection.ExecSQL(AbstractJdbc1Connection.java:505)
at org.postgresql.jdbc1.AbstractJdbc1Statement.execute(AbstractJdbc1Statement.java:320)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:48)
at org.postgresql.jdbc1.AbstractJdbc1Statement.executeUpdate(AbstractJdbc1Statement.java:197)
at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeUpdate(WrappedPreparedStatement.java:324)
at net.sf.hibernate.persister.NormalizedEntityPersister.delete(NormalizedEntityPersister.java:609)
at net.sf.hibernate.impl.ScheduledDeletion.execute(ScheduledDeletion.java:29)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2382)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2340)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2204)
at org.springframework.orm.hibernate.SessionFactoryUtils$SpringSessionSynchronization.beforeCommit(SessionFactoryUtils.java:378)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:435)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:311)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:189)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:138)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:148)