Переход в спящий режим однонаправленной родительско-дочерней связи - delete() выполняет обновление дочерней таблицы вместо удаления
-
06-07-2019 - |
Вопрос
Если я удаляю запись из родительской таблицы, я хочу, чтобы соответствующие записи в дочерней таблице были удалены.Как я могу заставить Hibernate удалять из дочерней таблицы, а не пытаться обновить с помощью null?
Я использую Hibernate 3, но в данный момент не могу использовать аннотации.Я приложил копии HBM, DAO и т.д. Ниже.-- Заранее благодарю вас
При попытке удалить данные из таблиц в родительско-дочерней связи я получаю следующую ошибку:
Testcase: testDelete(com.dressbarn.imbo.model.data.hibernate.dao.CharityTransferDAOTest): Caused an ERROR
Hibernate flushing: Could not execute JDBC batch update; uncategorized SQLException for SQL [update RMS12.DRS_CHARITY_TRANSFER_ITEM set TSF_NO=null, TSF_SEQ_NO=null where TSF_NO=?]; SQL state [72000]; error code [1407]; ORA-01407: cannot update ("RMS12"."DRS_CHARITY_TRANSFER_ITEM"."TSF_NO") to NULL
; nested exception is java.sql.BatchUpdateException: ORA-01407: cannot update ("RMS12"."DRS_CHARITY_TRANSFER_ITEM"."TSF_NO") to NULL
org.springframework.jdbc.UncategorizedSQLException: Hibernate flushing: Could not execute JDBC batch update; uncategorized SQLException for SQL [update RMS12.DRS_CHARITY_TRANSFER_ITEM set TSF_NO=null, TSF_SEQ_NO=null where TSF_NO=?]; SQL state [72000]; error code [1407]; ORA-01407: cannot update ("RMS12"."DRS_CHARITY_TRANSFER_ITEM"."TSF_NO") to NULL
; nested exception is java.sql.BatchUpdateException: ORA-01407: cannot update ("RMS12"."DRS_CHARITY_TRANSFER_ITEM"."TSF_NO") to NULL
Caused by: java.sql.BatchUpdateException: ORA-01407: cannot update ("RMS12"."DRS_CHARITY_TRANSFER_ITEM"."TSF_NO") to NULL
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:498)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:12368)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
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)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:578)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:662)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:314)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:629)
at com.dressbarn.imbo.model.data.hibernate.dao.CharityTransferDAO$$EnhancerByCGLIB$$6a21cd58.delete(<generated>)
at com.dressbarn.imbo.model.data.hibernate.dao.CharityTransferDAOTest.testDelete(CharityTransferDAOTest.java:112)
at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
Мои таблицы следующие:
Родитель:
CREATE TABLE DRS_CHARITY_TRANSFER
(
TSF_NO NUMBER(10) NOT NULL Primary Key,
FROM_LOC NUMBER(10),
CHARITY_LOC_ID NUMBER(10),
STATUS VARCHAR2(1 CHAR),
CREATE_DATE DATE,
EXT_REF_NO VARCHAR2(30 CHAR),
COMMENT_DESC VARCHAR2(2000 CHAR),
USER_ID VARCHAR2(30 CHAR)
)
Ребенок:
CREATE TABLE DRS_CHARITY_TRANSFER_ITEM
(
TSF_NO NUMBER(10) NOT NULL PRIMARY KEY,
ITEM VARCHAR2(25 BYTE) NOT NULL PRIMARY KEY,
TSF_SEQ_NO INTEGER,
TSF_QTY INTEGER
)
HBM XML
<hibernate-mapping package="com.dressbarn.imbo.model.data.hibernate.transfer" schema="RMS12">
<class name="CharityTransfer" table="DRS_CHARITY_TRANSFER">
<id name="transferNumber" column="TSF_NO" unsaved-value="undefined">
</id>
<property column="FROM_LOC" length="10" name="fromLocation" type="java.lang.Long"/>
<property column="CHARITY_LOC_ID" length="10" name="toCharityLocId" type="java.lang.Long"/>
<property column="STATUS" name="status" type="string"/>
<property column="EXT_REF_NO" name="documentNumber" type="string"/>
<property column="COMMENT_DESC" name="comment" type="string"/>
<property column="CREATE_DATE" name="createDate" type="string"/>
<property column="USER_ID" name="userId" type="string"/>
<list name="charityTransferItemList" cascade="all-delete-orphan" lazy="false">
<key column="TSF_NO" />
<list-index column="TSF_SEQ_NO"/>
<one-to-many class="CharityTransferItem" />
</list>
</class>
<class name="CharityTransferItem" table="DRS_CHARITY_TRANSFER_ITEM">
<id name="item" column="TSF_NO" unsaved-value="undefined">
</id>
<property column="ITEM" name="item" type="string"/>
<property column="TSF_SEQ_NO" length="10" name="sequence" type="integer"/>
<property column="TSF_QTY" length="12" name="quantity" type="long"/>
</class>
ДАО
public class CharityTransferDAO extends HibernateDaoSupport implements ICharityTransfer {
public void delete(CharityTransfer charityTransfer) throws IMADataException {
try {
getSessionFactory()
.getCurrentSession()
.delete(charityTransfer);
}
catch (HibernateException e) {
throw new IMADataException("failed to delete charity shipping information", e);
}
}
Решение
Я столкнулся с этой ошибкой ВСЕ время.
Просто поставьте inverse="true" на отношение, и ваша проблема исчезнет!
<list name="charityTransferItemList" inverse="true" cascade="all-delete-orphan" lazy="false" >
<key column="TSF_NO" />
<list-index column="TSF_SEQ_NO"/>
<one-to-many class="CharityTransferItem" />
</list>
По сути, инверсия сообщит hibernate, что дочерний элемент не может существовать без родительского элемента, тем самым заставляя hibernate удалять дочерний элемент.
Сказав это, вам также нужно будет удалить объект charityTransfer из родительской коллекции.
Другие советы
(Примечание:Этот вопрос был поднят как неправильный двумя пользователями).
В документах Hibernate говорится, что вы можете просто пометить ключевой столбец как not-null="true"
:
<list name="charityTransferItemList" cascade="all,delete-orphan" lazy="false">
<key column="TSF_NO" not-null="true" />
<list-index column="TSF_SEQ_NO"/>
<one-to-many class="CharityTransferItem" />
</list>
От Перевод документа в спящий режим для коллекций:
Если столбец внешнего ключа ассоциации объявлен NOT NULL, вы должны объявить сопоставление not-null="true" или использовать двунаправленную ассоциацию с отображением коллекции с пометкой inverse="true".Смотрите обсуждение двунаправленных ассоциаций позже для получения дополнительной информации в этой главе.
Я также думаю, что в вашем каскадном стиле есть опечатка (all-delete-orphan
должно быть all,delete-orphan
).