2009-06-18 17 views
8

親テーブルからレコードを削除すると、子テーブルの対応するレコードを削除します。 nullで更新しようとするのではなく、HibernateをChildテーブルから削除するにはどうすればよいですか?Hibernate単方向親子関係 - 削除の代わりに子テーブルの更新を実行します

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

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

答えて

11

は、私はこのエラーすべて時間に遭遇しました。

関係に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> 

基本的には逆に、それによって子供を削除するには休止状態引き起こし、子が親なしでは存在できない冬眠教えてくれます。

このことから、charityTransferオブジェクトも親のコレクションから削除する必要があります。

+0

私は、逆は双方向関係にのみ関連すると考えました。つまり、関係のどちら側を「王」とみなすべきかをHibernateに伝えます。私は間違っていますか? – waxwing

+0

マイク、 ありがとうございます!それがトリックでした。 マーク –

+1

inverse = "true"をデフォルトにして、それを削除するかどうかを検討するという習慣を持つことをお勧めします。私はinverse = "true"を入れなければならなかった回数を片手に数えることができると思います。 –

1

(注:これは2人のユーザーによる誤った回答として提起されています)。 Hibernate doc on collectionsから

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

Hibernateのドキュメントはあなただけnot-null="true"としてキー列をマークすることができると言う

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.

私はまた、あなたのカスケードスタイルにタイプミスがあると思います(all-delete-orphanあるべきall,delete-orphan)。

+0

'not-null = true'または' nullable = false'アノテーションはこれを制御しません。自分でテストしました。それは 'inverse = true'、または' mappedBy = "fieldName"のプロパティによってのみ制御されます。 – Shinzul

+0

ありがとう:)承認された解決策によっても説明されています。私はそれを無効とマークするために答えを更新しました。 – jjmontes

関連する問題