Unidirektional Eltern- / Kind-Beziehung Hibernate - löschen () führt Update auf Kindertisch statt löschen
-
06-07-2019 - |
Frage
Wenn ich einen Datensatz aus der übergeordneten Tabelle löschen mag ich die entsprechende Datensätze in der untergeordneten Tabelle gelöscht werden. Wie kann ich Hibernate aus der Child-Tabelle löschen machen anstatt versuchen, mit einem Null zu aktualisieren?
Ich verwende Hibernate 3, aber kann Anmerkungen zu diesem Zeitpunkt nicht verwenden. Ich habe beigefügten Kopien von HBM, DAO etc unten. - Vielen Dank im Voraus
Beim Versuch, Daten aus Tabellen in Parent zu löschen / Kind-Beziehung ich folgende Fehlermeldung erhalten:
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)
Meine Tabellen sind:
Eltern :
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)
)
Child:
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>
DAO
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);
}
}
Lösung
Ich traf diesen Fehler alle die Zeit.
Nur ein inverser setzen = "true" auf die Beziehung und das Problem weggeht!
<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>
Im Grunde genommen wird die inverse sagen, das Kind überwintern kann nicht ohne einen Elternteil bestehen, wodurch winter wodurch das Kind zu löschen.
Having said that, Sie werden auch als auch das charityTransfer Objekt aus der Sammlung in den übergeordneten entfernen müssen.
Andere Tipps
(Hinweis: Dies wird als eine falsche Antwort von zwei Benutzern erhoben worden ist).
Hibernate docs sagen, Sie können nur die Schlüsselspalte als not-null="true"
markieren:
<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>
Wenn die Fremdschlüsselspalte eines Vereins erklärt NOT NULL, müssen Sie die Zuordnung nicht-null = „true“ oder erklären verwenden bidirektionale Verbindung mit der Sammlung Mapping markiert invers = "true". Siehe die Diskussion über bidirektionale Assoziationen später in diesem Kapitel für weitere Informationen.
Ich denke, es gibt auch einen Tippfehler in der Kaskade Stil (all-delete-orphan
sollte all,delete-orphan
sein).