Hi all,
I have a many-to-many mapping between
InitialStateType and
Position and a one-to-many mapping between
ActionsType and
Position. Both mappings are unidirectional. A row in
Position can be shared by
InitialStateType and
ActionsType (both lists have a reference on the same object in Java). Everything works fine except when I try to delete an instance of
InitialStateType or
ActionsType. I get a constraint violation from the database.
As the same instances of
Position can be shared by
InitialStateType and
ActionsType, I think that, if I remove e.g. an instance of
InitialStateType, Hibernate try to remove
Position which are not referenced by any
InitialStateType anymore (that is correct) but does not look if these
Position are still referenced by
ActionsType.
Hibernate should remove a
Position only if it is not referenced by
InitialStateType AND ActionsType anymore.
I have tried different cascading type without success. Is there a way to do this with Hibernate? How to correctly handle shared instances (one element referenced by multiple lists)?
Thank you
P.S. The mapping files are generated using HyperJAXB2.
Hibernate version: 3.2.3.ga
Mapping documents:
Code:
<hibernate-mapping auto-import="false" default-cascade="all-delete-orphan" default-lazy="false">
<class discriminator-value="[xxx.bean.InitialStateType]"
name="xxx.bean.InitialStateType"
table="InitialStateType">
<id access="org.jvnet.hyperjaxb2.runtime.hibernate.accessor.CheckingPropertyAccessor"
name="Hjid"
type="org.hibernate.type.LongType">
<generator class="native"/>
</id>
<discriminator type="org.hibernate.type.StringType">
<column name="Hjtype"/>
</discriminator>
<list access="org.jvnet.hyperjaxb2.runtime.hibernate.accessor.ListAccessor"
name="Positions"
table="InitialStateType_Positions">
<key>
<column name="InitialStateType_Positions_H_0"/>
</key>
<list-index>
<column name="InitialStateType_Positions_H_1"/>
</list-index>
<many-to-many class="xxx.bean.Position">
<column name="Position__Positions_Hjchildid"/>
</many-to-many>
</list>
...
<subclass discriminator-value="xxx.bean.InitialStateType"
name="xxx.bean.impl.InitialStateTypeImpl"/>
</class>
</hibernate-mapping>
Code:
<hibernate-mapping auto-import="false" default-cascade="all-delete-orphan" default-lazy="false">
<class discriminator-value="[xxx.bean.ActionsType]"
name="xxx.bean.ActionsType"
table="ActionsType">
<id access="org.jvnet.hyperjaxb2.runtime.hibernate.accessor.CheckingPropertyAccessor"
name="Hjid"
type="org.hibernate.type.LongType">
<generator class="native"/>
</id>
<discriminator type="org.hibernate.type.StringType">
<column name="Hjtype"/>
</discriminator>
<list access="org.jvnet.hyperjaxb2.runtime.hibernate.accessor.ListAccessor"
name="Positions"
table="ActionsType_Positions">
<key>
<column name="ActionsType_Positions_Hjid"/>
</key>
<list-index>
<column name="ActionsType_Positions_Hjindex"/>
</list-index>
<one-to-many class="xxx.bean.Position"/>
</list>
...
<subclass discriminator-value="xxx.bean.ActionsType"
name="xxx..impl.ActionsTypeImpl"/>
</class>
</hibernate-mapping>
Code:
<hibernate-mapping auto-import="false" default-cascade="all-delete-orphan" default-lazy="false">
<class discriminator-value="[xxx.bean.Position]"
name="xxx.bean.Position"
table="Position_">
<id access="org.jvnet.hyperjaxb2.runtime.hibernate.accessor.CheckingPropertyAccessor"
name="Hjid"
type="org.hibernate.type.LongType">
<generator class="native"/>
</id>
<discriminator type="org.hibernate.type.StringType">
<column name="Hjtype"/>
</discriminator>
<property access="org.jvnet.hyperjaxb2.runtime.hibernate.accessor.CheckingPropertyAccessor"
name="Speed">
<column name="Speed"/>
<type name="org.hibernate.type.DoubleType"/>
</property>
<property access="org.jvnet.hyperjaxb2.runtime.hibernate.accessor.CheckingPropertyAccessor"
name="Longitude">
<column name="Longitude"/>
<type name="org.hibernate.type.DoubleType"/>
</property>
...
<subclass discriminator-value="xxx.bean.Position"
name="xxx.bean.impl.PositionImpl"/>
</class>
</hibernate-mapping>
Full stack trace of any exception that occurs:Code:
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:92)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:222)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2479)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2697)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:74)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
....
Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`mission/InitialStateType_Positions`, CONSTRAINT `FK6D6552B2116044` FOREIGN KEY (`Position__Positions_Hjchildid`) REFERENCES `Position_` (`Hjid`))
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1213)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:912)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 28 more
Name and version of the database you are using: MySQL 5.0.38 / PostgreSQL 8.2.4