When a class contains a map of composite elements, and the composite element is nullable, deletion of an instance of the class fails when the map contains a null composite element. I have worked around this problem by ensuring that the composite element is never null, but this seems to be scenario that hibernate should handle.
The following mapping is an example only.
Hibernate version: 3.2.5.ga
Mapping documents:
Code:
<class name="Parent" table="parent">
<id...>
<version...>
<map name="children" table="children">
<key column="parent_id" not-null="true"/>
<map-key column="child_name" type="string"/>
<composite-element class="Child">
<property name="data1" type="string"/>
<property name="data2" type="string"/>
</composite-element>
</map>
</class>
Schema:Code:
CREATE TABLE parent
(
serial_id SERIAL NOT NULL,
stamp INTEGER NOT NULL,
PRIMARY KEY (serial_id) CONSTRAINT parent__pk
);
CREATE TABLE children
(
parent_id INTEGER NOT NULL REFERENCES parent(serial_id),
child_name NVARCHAR(100) NOT NULL,
data1 NVARCHAR(100),
data2 NVARCHAR(100),
PRIMARY KEY (parent_id, child_name)
);
Code between sessionFactory.openSession() and session.close():Code:
Session s = ...;
Parent p = ...;
s.delete(p);
NOTE: The problem that I am reporting here only occurs when the composite-element in the "children" map is null. ie. both data1 and data2 columns are null, and so the map contains a null value.Full stack trace of any exception that occurs:Code:
11/23-08:19:34.631,WARN ,http-0.0.0.0-3765-1 : org.hibernate.util.JDBCExceptionReporter: SQL Error: -692, SQLState: 23000
11/23-08:19:34.631,ERROR,http-0.0.0.0-3765-1 : org.hibernate.util.JDBCExceptionReporter: Key value for constraint (danielbe.parent__pk) is still being referenced.
11/23-08:19:34.632,ERROR,http-0.0.0.0-3765-1 : .event.def.AbstractFlushingEventListener: Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not delete: [Parent#1]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2541)
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:250)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:146)
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)
Name and version of the database you are using: Informix 7.3
The generated SQL (show_sql=true):
The generated SQL only shows a delete statement being generated for the parent table, not for the child table.