2

2 つのオブジェクトがあります。DocumentDocumentBatch

書類

public class Document implements Serializable {

....
private String documentId;
private DocumentBatch documentBatch;
....}

ドキュメントバッチ

public class DocumentBatch implements Serializable {


private String batchId;

private List<Document> lDocuments = new LinkedList<Document>();
....}

休止状態のマッピング:

<class name="Document" table="DOCUMENTS">
  .....
  <id name="documentID" column="DOCUMENT_ID" type="string" />
  <many-to-one name="documentBatch" class="DocumentBatch" not-null="false" 
  cascade="save-update" lazy="false" insert="false" update="false">
        <column name="BATCH_ID" not-null="true" />
    </many-to-one>
  ......
</class>


<class name="DocumentBatch" table="DOCUMENT_BATCHES">
     <id name="batchId" column="BATCH_ID" type="string" /> 
     <list name="lDocuments" table="DOCUMENTS" cascade="all"
        inverse="false" lazy="false" mutable="true">
        <key not-null="true">
            <column name="BATCH_ID" />
        </key>
        <list-index column="LIST_INDEX" base="0" />
        <one-to-many class="Document" />
       </list>
     ......
 </class>

DocumentBatchのリストがありDocument、テストケースを実行するたびに、同じ主キーでオブジェクトsession.saveOrUpdate(documentBatch)を更新するために使用しDocumentBatchますが、ドキュメント オブジェクトの新しい生成リストを使用します (すべてのオブジェクトは新しく生成されます)。

Hibernate は、ドキュメントの新しいリスト全体をインデックス付きで保存して更新DocumentBatchしますが、リストの古い要素は削除しません。

したがって、テストケースを 2 回実行すると、毎回Documentのリストに5 つの Obj があり、最終的には 10 個の obj になります。index=0 の 2 つ、index=1 の 2 つなど。

したがって、リストは更新されず、新しいリストのみが保存されます。古いリストの要素はデータベースにあります。取得しようとするとDocumentBatch, DocumentBatch、古いオブジェクトのリストがあります。

どうすればこの問題を解決できますか? どこで間違いを犯しましたか?どうもありがとう。

更新 1: UnitTestCase

 @Test
public void testSaveDocumentBatch() throws Throwable {
....
String batchId = "500700";
DocumentBatch documentBatch = new DocumentBatch(batchId, name);
    ....
    for (int i = 0; i < 5; i++) {
    String documentID = SessionIdentfierGenerator.nextSessionId();//generatting Id
    Document document = new Document(documentID);
    documentBatch.insertDocument(document);
}
    ....
    session.saveOrUpdate(documentBatch);
    ....}

また、クラス DocumentBatch のメソッド insertDocument(Document document):

public class DocumentBath{
.....
private List<Document> lDocuments = new LinkedList<Document>();
.....
public void insertDocument(Document document) {
    lDocuments.add(document); // lDocuments is a list DocumentBatch
    document.setDocumentBatch(this);
}
.....}

更新 2: Oracle DB スクリプト:

ドキュメントの

CREATE TABLE DOCUMENTS(
DOCUMENT_ID VARCHAR2(255 CHAR) NOT NULL,
BATCH_ID VARCHAR2(255 CHAR) NOT NULL,
...);  


CREATE UNIQUE INDEX PK_DOCUMENT ON DOCUMENTS (DOCUMENT_ID); 
ALTER TABLE DOCUMENTS ADD (CONSTRAINT PK_DOCUMENT PRIMARY KEY (DOCUMENT_ID) USING INDEX PK_DOCUMENT); 

ALTER TABLE DOCUMENTS ADD (CONSTRAINT FK_DOCUMENT_BATCH_ID FOREIGN KEY (BATCH_ID) REFERENCES DOCUMENT_BATCHES (BATCH_ID) ON DELETE CASCADE);

DocumentBatch の

CREATE TABLE DOCUMENT_BATCHES(
BATCH_ID VARCHAR2(255 CHAR)     NOT NULL
...);

ALTER TABLE DOCUMENT_BATCHES ADD (
PRIMARY KEY (BATCH_ID));
4

1 に答える 1

0

ほらね。テスト ケースでは、DB に既に存在するエンティティの新しいエンティティ オブジェクトを作成しています。これは休止状態を混乱させ、休止状態は既存のドキュメントを削除することにはなりません。

String batchId = "500700";
    DocumentBatch documentBatch = new DocumentBatch(batchId, name);

この「new DocumentBatch(batchId, name)」の代わりに、最初に get() または load() を使用して、ID 500700 で既存の DocumentBatch オブジェクトを取得します。既存のオブジェクトを取得したら、以下の手順を実行します。

1) clearExistingDocuments() などのメソッドを作成します。このメソッドでは、最初にドキュメントのリストを繰り返し処理し、BATCH_ID を null にします。反復が完了したら、それらのドキュメントをすべてリストから削除します。

2) 新しく作成されたドキュメントを同じ空のリストに追加します。新しいリスト インスタンスを作成しないでください。同じ空のリスト インスタンスを使用し、新しいドキュメントを追加します。

これで問題は解決するはずです。これらの手順により、休止状態は最初にいくつかの既存の値があったことを認識し、現在はそれらが明示的に削除されているため、休止状態は関連する削除クエリを起動します。必要に応じて orphan-delete も使用してください。これは、孤立した DOcument オブジェクトをドキュメント テーブルに保持する代わりに削除します。

于 2012-11-16T12:42:35.567 に答える