Hibernate unidirecional relação pai / filho - delete () Update executa na tabela filho em vez de exclusão

StackOverflow https://stackoverflow.com/questions/1012874

Pergunta

Se eu excluir um registro da tabela pai eu quero que os registros correspondentes na tabela a criança a ser excluído. Como posso fazer Hibernate excluir da tabela filho em vez de tentativa de atualização com um nulo?

Eu estou usando Hibernate 3, mas não pode usar anotações neste momento. Anexei cópias de HBM, DAO etc abaixo. - Agradecemos antecipadamente

Ao tentar eliminar dados de tabelas em Parent relacionamento / criança eu recebo o seguinte erro:

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)

As minhas tabelas são:

pai :

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

Criança:

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);
      }    
}
Foi útil?

Solução

Eu encontrei este erro todas o tempo.

Basta colocar um inverse = "true" no relacionamento e seu problema vai embora!

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

Basicamente o inverso irá dizer hibernate a criança não pode existir sem um pai, causando hibernação para eliminar a criança.

Dito isto, você também vai precisar para remover o objeto charityTransfer da coleção no pai também.

Outras dicas

(Nota: Este foi criado como uma resposta incorreta por dois usuários).

docs Hibernate dizer que você pode apenas marcar a coluna de chave 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>

A partir Hibernate doc em coleções :

Se a coluna de chave estrangeira de uma associação é declarado NOT NULL, você deve declarar o mapeamento não-null = "true" ou usar um associação bidirecional com o mapeamento de recolha marcado inverse = "true". Veja a discussão de associações bidirecionais mais tarde neste capítulo para obter mais informações.

Eu também acho que há um erro de digitação no seu estilo em cascata (all-delete-orphan deve ser all,delete-orphan).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top