Hi all,
We've got following situation.
Module table.
Code:
<hibernate-mapping>
<class name="net.lidotech.biceps.domain.Module" table="module" dynamic-update="false" dynamic-insert="false" mutable="true">
<id name="moduleId" column="module_id" type="long" unsaved-value="0">
<generator class="native">
</generator>
</id>
<set name="dataUnits" lazy="false" cascade="all" sort="unsorted">
<key column="module_id"/>
<one-to-many class="net.lidotech.biceps.domain.DataUnit"/>
</set>
<property name="description" type="java.lang.String" update="true" insert="true" column="description" length="255" not-null="true" unique="false"/>
<property name="name" type="java.lang.String" update="true" insert="true" column="name" length="55" not-null="true" unique="true"/>
</class>
</hibernate-mapping>
DataUnit table.
Code:
<hibernate-mapping>
<class name="net.lidotech.biceps.domain.DataUnit" table="data_unit" dynamic-update="false" dynamic-insert="false" mutable="true">
<id name="dataUnitId" column="data_unit_id" type="long" unsaved-value="0">
<generator class="native">
</generator>
</id>
<property name="name" type="java.lang.String" update="true" insert="true" column="name" length="55" not-null="true" unique="false"/>
<many-to-one name="module" class="net.lidotech.biceps.domain.Module" cascade="none" outer-join="auto" update="true" insert="true" column="module_id" not-null="true"/>
</class>
</hibernate-mapping>
As you can see the there is relationship (cascade=all) one-to-many between Module and DataUnit tables. The problem occurs when we're trying to update Module which already has some DataUnits.
Following exception occurs:
Code:
50079 [main ] DEBUG net.sf.hibernate.collection.BasicCollectionPersister - Deleting collection: [net.lidotech.biceps.domain.Module.dataUnits#22]
50079 [main ] DEBUG net.sf.hibernate.impl.BatcherImpl - about to open: 0 open PreparedStatements, 0 open ResultSets
50079 [main ] DEBUG net.sf.hibernate.SQL - update data_unit set module_id=null where module_id=?
Hibernate: update data_unit set module_id=null where module_id=?
50079 [main ] DEBUG net.sf.hibernate.impl.BatcherImpl - preparing statement
50079 [main ] DEBUG net.sf.hibernate.type.LongType - binding '22' to parameter: 1
50095 [main ] DEBUG net.sf.hibernate.impl.BatcherImpl - done closing: 0 open PreparedStatements, 0 open ResultSets
50095 [main ] DEBUG net.sf.hibernate.impl.BatcherImpl - closing statement
50095 [main ] DEBUG net.sf.hibernate.util.JDBCExceptionReporter - SQL Exception
java.sql.SQLException: Cannot insert the value NULL into column 'module_id', table 'TEST_BICEPS.dbo.data_unit'; column does not allow nulls. UPDATE fails.
at net.sourceforge.jtds.jdbc.SqlMessage.toSQLException(Unknown Source)
at net.sourceforge.jtds.jdbc.SQLWarningChain.addOrReturn(Unknown Source)
at net.sourceforge.jtds.jdbc.TdsStatement.getMoreResults(Unknown Source)
at net.sourceforge.jtds.jdbc.TdsStatement.executeCallImpl(Unknown Source)
at net.sourceforge.jtds.jdbc.TdsStatement.internalExecuteCall(Unknown Source)
at net.sourceforge.jtds.jdbc.PreparedStatement_base.execute(Unknown Source)
at net.sourceforge.jtds.jdbc.PreparedStatement_base.executeUpdate(Unknown Source)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:233)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at net.sf.hibernate.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:500)
at net.sf.hibernate.impl.ScheduledCollectionRemove.execute(ScheduledCollectionRemove.java:22)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2385)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2340)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2207)
at net.lidotech.biceps.dao.hib.Dao.update(Dao.java:531)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.springframework.aop.framework.AopProxyUtils.invokeJoinpointUsingReflection(AopProxyUtils.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:201)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
at org.springframework.orm.hibernate.HibernateInterceptor.invoke(HibernateInterceptor.java:84)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:135)
at $Proxy15.update(Unknown Source)
As you can see Hibernate tries to update Module's DataUnit's collection and tries to set null for all DataUnit.module_id, this generates an error because that field cannot be null. How can we solve that, we know that the easies way is to set the (fk)module_id field as not null but maybe there is a hibernate way to fix that :).
Best regards
Hytrus