在eclipselink中的两个有序列表之间移动实体

时间:2016-09-15 09:08:36

标签: jpa eclipselink

我们正在使用eclipselink来保存我们的实体。在多种情况下,我们订购了包含一个实体子项的列表。当一个实体从其中一个列表移动到另一个列表时,我们经常会遇到其中一个列表中的无效订单问题(我们正在移动的列表中的空白或目标列表中的重复)。

父实体看起来像这样(我删除了大概不相关的属性,方法和注释):

@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Document implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    @OrderColumn
    @JoinColumn(name = "document_id")
    private List<Row> rows = new ArrayList<>();

}

此案例的子实体:

@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Row implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

}

要使用此代码移动我们开始的实体:

    document.getRows().add(rowIndex, row);
    documentRepository.save(document);

出现问题时,我们首先添加了代码以从旧文档中删除行:

    if (oldDocument != null && !oldDocument.equals(document)) {
        oldDocument.getRows().remove(row);
        documentRepository.save(oldDocument);
    }

有一段时间,它还有助于更改代码以将文档从save保存到saveAndFlush(不确定为什么会出现这种情况)。然而,这似乎不再有用了。

这些更改导致当前代码:

    document.getRows().add(rowIndex, row);
    documentRepository.saveAndFlush(document);

    if (oldDocument != null && !oldDocument.equals(document)) {
        oldDocument.getRows().remove(row);
        documentRepository.saveAndFlush(oldDocument);
    }

在执行任何操作之前,数据库中的行如下所示:

id       document_id  rows_order
113940   113306       0
114041   113306       1
114044   113306       2
115671   115129       0
115674   115129       1

将行114041移动到文档115129后,这是结果数据:

id       document_id  rows_order
113940   113306       0
114044   113306       2
115671   115129       0
114041   115129       1
115674   115129       2

rows_order中的差距已经显得可疑,并且在文档末尾插入新行时会出现问题:

@Transactional
public void addRow() {
    Document document = documentRepository.getOne(113306);
    Row newRow = new Row();
    rowRepository.save(newRow);
    document.getRows().add(2, newRow);
    documentRepository.saveAndFlush(document);
}

这是提交事务时出现的错误消息:

Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "unique_document_id_rows_order"
  Detail: Key (document_id, rows_order)=(113306, 2) already exists.
Error Code: 0
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:70)
    at com.dbcentral.service.DocumentService.addRow(DocumentService.java:100)

document.getRows()是一个包含两个元素的列表,因此在末尾添加一个元素应该可以在索引2处添加它。

我们可以通过删除document_id和rows_order的约束来避免该错误,但这会导致重复的rows_order条目,如下所示:

id       document_id  rows_order
113940   113306       0
114044   113306       2
115676   113306       2
115671   115129       0
114041   115129       1
115674   115129       2

由于评论中的想法,我们尝试将@ChangeTracking注释添加到Document实体。然而,这两项政策似乎都没有改变任何内容。

我们目前正在以正确的方式在有序列表之间移动实体,还是我们可能遗漏了什么?

另一个想法是在每次移动后运行一个sql,更正order列。关于这一点,我们不确定在应用程序运行时是否操作该列是个好主意。

0 个答案:

没有答案