2009-06-18 16 views
8

Si elimino un registro de la tabla principal, quiero que se eliminen los registros correspondientes en la tabla secundaria. ¿Cómo puedo hacer que Hibernate elimine de la tabla Child en lugar de intentar actualizar con un nulo?Hibernar Relación unidireccional padre/hijo - delete() realiza la actualización en la tabla secundaria en lugar de eliminar

Estoy usando Hibernate 3 pero no puedo usar anotaciones en este momento. He adjuntado copias de HBM, DAO, etc. a continuación. - Gracias de antemano

Al intentar eliminar datos de las tablas en relación Padre/Hijo me sale el siguiente error:

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) 

Mis cuadros son:

Padres:

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

Niño:

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

Respuesta

11

me encontré con este error todo el tiempo.

¡Simplemente ponga un inverso = "verdadero" en la relación y su problema desaparecerá!

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

Básicamente la inversa le dirá hibernar el niño no puede existir sin un padre, lo que provoca hibernación para eliminar el niño.

Dicho esto, también deberá eliminar el objeto charityTransfer de la colección en el elemento principal.

+0

Pensé que invertir solo es relevante para relaciones bidireccionales. Es decir, le dice a Hibernate qué lado de la relación debería considerarse "rey". ¿Estoy equivocado? – waxwing

+0

Mike, ¡Gracias! Eso hizo el truco. Mark –

+1

Le sugiero que adquiera el hábito de hacer que inverse = "true" sea el valor predeterminado, y luego considerar si debe eliminarlo o no.Creo que puedo contar con una mano la cantidad de veces que no he tenido que poner el inverso = "verdadero" en. –

1

(Nota: Dos usuarios han planteado una respuesta incorrecta).

docs

Hibernate dicen que sólo puede marcar la columna de clave como 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> 

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

También creo que hay un error tipográfico en su estilo en cascada (all-delete-orphan debería haber all,delete-orphan).

+0

La anotación 'not-null = true' o' nullable = false' no controla esto, lo he probado yo mismo. Está controlado exclusivamente por las propiedades 'Inverse = true', o' mappedBy = "fieldName" '. – Shinzul

+0

Gracias :). También descrito por la solución aceptada. He actualizado la respuesta para marcarla como inválida. – jjmontes

Cuestiones relacionadas