2009-06-18 11 views
8

Se si elimina un record dalla tabella padre, desidero eliminare i record corrispondenti nella tabella figlio. Come posso rendere Hibernate delete dalla tabella Child piuttosto che tentare di aggiornare con un null?Hibernate Relazione padre/figlio unidirezionale - delete() esegue l'aggiornamento sulla tabella figlio anziché eliminare

Sto utilizzando Hibernate 3 ma al momento non posso usare annotazioni. Di seguito ho allegato copie di HBM, DAO ecc. - Grazie in anticipo

Quando si tenta di cancellare i dati dalle tabelle in Parent/rapporto Bambino ottengo il seguente errore:

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) 

miei tavoli sono:

Parent:

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) 
) 

Bambino:

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); 
     }  
} 

risposta

11

ho incontrato questo errore tutto il tempo.

Basta mettere un inverso = "true" sulla relazione e il problema andrà via!

<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> 

In pratica l'inverso dirà ibernare il bambino non può esistere senza un genitore, causando in tal modo ibernazione per eliminare il bambino.

Detto questo, è necessario rimuovere anche l'oggetto charityTransfer dalla raccolta nel genitore.

+0

Ho pensato che l'inverso è rilevante solo per le relazioni bidirezionali. I.e, dice ad Hibernate quale parte della relazione dovrebbe essere considerata "re". Mi sbaglio? – waxwing

+0

Mike, Grazie! Questo ha fatto il trucco. Mark –

+1

Vorrei suggerire di prendere l'abitudine di fare inverse = "true" l'impostazione predefinita, e quindi considerare se dovresti rimuoverlo o meno.Penso di poter contare su un lato il numero di volte in cui non ho dovuto inserire l'inverso = "true" in. –

1

(Nota: questa è stata sollevata come risposta errata da due utenti).

Hibernate documenti dicono che si può solo segnare la colonna chiave come 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> 

Da Hibernate doc on collections:

If the foreign key column of a association is declared NOT NULL, you must declare the mapping not-null="true" or use a bidirectional association with the collection mapping marked inverse="true". See the discussion of bidirectional associations later in this chapter for more information.

Penso anche che ci sia un errore di battitura nel tuo stile a cascata (all-delete-orphan dovrebbe essere all,delete-orphan).

+0

L'annotazione 'not-null = true' o' nullable = false' non controlla questo, l'ho provato io stesso. È controllato esclusivamente dalle proprietà 'inverse = true', o' mappedBy = "fieldName" '. – Shinzul

+0

Grazie :). Descritto anche dalla soluzione accettata. Ho aggiornato la risposta per contrassegnarla come non valida. – jjmontes

Problemi correlati