gpt4 book ai didi

java - Hibernate 在不删除旧元素的情况下将新元素保存在列表中

转载 作者:行者123 更新时间:2023-11-29 09:08:53 25 4
gpt4 key购买 nike

我有两个对象; 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>();
....}

Hibernate 映射:

<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,保存带有索引的全新文档列表,但不会删除列表中的旧元素。

所以当我运行我的测试用例两次并且每次 Document 列表都有 5 个 Obj 时,我将有最后 10 个 obj。两个索引=0,两个索引=1,等等。

所以它不会更新列表,只会保存新列表。旧列表的元素可以在数据库中找到。当我尝试获取 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 数据库脚本:

文档的

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

最佳答案

给你。在您的测试用例中,您正在为数据库中已经存在的实体创建新的实体对象。这混淆了 hibernate 和 hibernate 不会删除现有文档。

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

而不是这个“new DocumentBatch(batchId, name)”,首先使用 get() 或 load() 通过 id 500700 获取现有的 DocumentBatch 对象。获取现有对象后,然后执行以下步骤。

1) 创建一个方法,例如清除现有文档()。在此方法中,首先遍历文档列表并使 BATCH_ID 为空。一旦迭代完成,然后从列表中删除所有这些文档。

2) 现在在同一个空列表中添加新创建的文档。避免创建新的列表实例。使用相同的空列表实例并添加新文档。

这应该可以解决问题。由于这些步骤,hibernate 将知道最初存在一些现有值,现在这些值已被明确删除,因此 hibernate 将触发相关的删除查询。如果需要,也可以使用孤立删除。这将删除孤立的 DOcument 对象,而不是将它们保留在文档表中。

关于java - Hibernate 在不删除旧元素的情况下将新元素保存在列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13415802/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com