今日在项目中,遇到一个让人头疼的问题。问题涉及到两个存在级联关系的两张表 T_CONSTRUCT_OPERATION(主表)和 T_CONSTRUCT_PRACTI(子表)。
CREATE TABLE T_CONSTRUCT_OPERATION{
CONSTRUCT_ID BIGINT IDENTITY PRIMARY KEY -- 主表ID(主键)
}
<pre name="code" class="sql">CREATE TABLE T_CONSTRUCT_PRACTI{
CONSTRUCT_PRACTI_ID BIGINT IDENTITY PRIMARY KEY, -- 子表ID(主键)
CONSTRUCT_ID BIGINT NOT NULL -- 主表ID
}
T_CONSTRUCT_OPERATION 表hbm文件片段:
<set name="constructRealPractiSet" lazy="true" cascade="all" inverse="false"
where = "TYPE = '1' " >
<key column="CONSTRUCT_ID" />
<one-to-many class="com.knight.emms.model.ConstructPracti" />
</set>
级联策略
cascade="all":所有情况下均进行级联操作
然而当对主表持久化对象进行update或merge操作时,总是会报
org.hibernate.util.JDBCExceptionReporter(JDBCExceptionReporter.java:234) - 不能将值 NULL 插入列 'CONSTRUCT_ID',表 'EMMS.dbo.T_CONSTRUCT_PRACTI';列不允许有 Null 值。UPDATE 失败。
查看hibernate执行的SQL语句:
<pre name="code" class="sql">Hibernate: insert into T_CONSTRUCT_OPERATION_TASK (CONSTRUCT_ID, CONTENTS, UNIT, TASK_TYPE, QUANTITY, UNIT_PRICE, SUMMARY, REMARK) values (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into T_CONSTRUCT_PRACTI (CONSTRUCT_ID, USER_ID, TYPE) values (?, ?, ?)
Hibernate: update T_CONSTRUCT_OPERATION_TASK set CONSTRUCT_ID=?, CONTENTS=?, UNIT=?, TASK_TYPE=?, QUANTITY=?, UNIT_PRICE=?, SUMMARY=?, REMARK=? where CONSTRUCT_TASK_ID=?
Hibernate: update T_CONSTRUCT_OPERATION_TASK set CONSTRUCT_ID=null where CONSTRUCT_ID=?
Hibernate: update T_CONSTRUCT_OPERATION_TASK set CONSTRUCT_ID=null where CONSTRUCT_ID=?
Hibernate: update T_CONSTRUCT_OPERATION_TASK set CONSTRUCT_ID=? where CONSTRUCT_TASK_ID=?
Hibernate: update T_CONSTRUCT_OPERATION_TASK set CONSTRUCT_ID=? where CONSTRUCT_TASK_ID=?
发现原来hibernate在处理一对多的级联关系的时候,如果需要对子表进行update修改数据,hibernate最后总会将子表中所有与主表关联的条目的关联ID置空,删除主从表之间的关联关系,然后再重新关联一次。
以保证数据库的关联数据与session中的保持一致。