Hibernate:在有序列表中删除后插入

时间:2015-10-15 12:11:52

标签: java hibernate collections

我已经为书籍清单(用户内部)+通常的getter / setter获得了以下映射:

@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
@JoinColumn(name = "book_id", nullable = false)
@IndexColumn(name = "order", nullable = false)
private List<Book> books = new ArrayList<Book>();

现在我正在为有两本书的用户这样做:

User user = getUser(...);
user.getBooks().remove(1); //Remove the last one
user.getBooks().add(new Book("New one!"));
update(user); // ends up calling session.merge()
然而,虽然新书得到了保留,但另一本书并未被删除。这是数据库之前/之后:

  id  | book_id | title  | order
------+---------+--------+-------
   20 |       1 | Book 1 |    0
   21 |       1 | Book 2 |    1

  id  | book_id | title    | order
------+---------+----------+-------
   20 |       1 | Book 1   |    0
   21 |       1 | Book 2   |    1
   22 |       1 | New one! |    1

如您所见,索引列重复。

仅在使用有序/索引集合时才会发生这种情况。如果我删除@IndexColumn注释,则代码段会按预期工作。但是我需要保持插入顺序。我使用的是Hibernate 3.5.6。

有什么想法吗?提前谢谢。

更新:如果不是第二个元素,我会删除第一个元素,它会得到妥善管理。

第二次更新:似乎更改了DAO图层以使用&#34; saveOrUpdate&#34;而不是&#34;合并&#34;使这个东西正常工作。但是,它不是一个解决方案,因为改变可能会破坏现有的遗留代码。

2 个答案:

答案 0 :(得分:1)

只是从集合中删除元素只对您的数据库与orphanRemoval结合使用 - 当您想要明确地执行此操作时,请使用例如你的实体经理:

Book book = user.getBooks().get(1);
entityManager.remove(book);

答案 1 :(得分:1)

级联所有持久性事件不包括孤儿,因此如果使用JPA 2或orphanRemoval=true,则可以使用CascadeType.DELETE_ORPHAN