gpt4 book ai didi

java - 在 JPA 中的两个相关实体中出现一些急切的 n 对 n 关系的更新

转载 作者:行者123 更新时间:2023-11-29 06:15:07 25 4
gpt4 key购买 nike

在 JPA 中更改两个实体之间的 n 对 n 关系的最佳方法是什么。

让我用一个例子来解释:假设我有一个 Author 和一个 Book 实体,其中 Book 可以有各种 AuthorAuthor 可以在各种 Book 上写作。该模型表示为 n 对 n 的热切关系:

@Entity
public class Author {
@ManyToMany(fetch=FetchType.EAGER)
private List<Book> books;
// ...
}

还有:

@Entity
public class Book {
@ManyToMany(fetch=FetchType.EAGER)
private List<Author> authors;
// ...
}

我想在这些实体中执行一系列操作 - 例如,将 Author 标记为 Book 的作者:

public class SomeService {
public void addAuthor(Book book, Author author) {
book.getAuthors().add(author);
em.persist(book);
}
}

或从作者的书中删除Book:

public class SomeOtherService {
public void removeBook(Author author, Book book) {
author.getBooks().remove(book);
em.persist(author);
}
}

但是,我希望在不更新的实体中注册更新。当我调用 addAuthor() 时,我希望更新的 Book 也出现在 Author 的书籍列表中。当我调用 removeBook() 时,我希望从 Book 的作者列表中删除 Author

如果代码如上,则不会发生。我目前的解决方案是在两个实体中执行相应的操作,或多或少如下所示:

public class SomeService {
public void addAuthor(Book book, Author author) {
book.getAuthors().add(author);
author.getBooks().add(book);
em.persist(book);
em.persist(author);
}
}

不过,这对我来说似乎是一个蹩脚的解决方案。所以,我的问题是:是否有更好的方法来做到这一点?

提前致谢?

最佳答案

这对我来说并不是一个蹩脚的解决方案,因为它对正在发生的事情非常明确,一个优点是你有一个非常明确的代码。但是,如果这对您来说过于明确,那么您有多种选择。

正如 Jay 建议的那样,您可以编写一个执行以下操作的 @PreUpdate 回调方法:

author.getBooks().add(book);

然而,要使其工作,您必须使用 @ManyToMany 注释的级联属性将更改级联到作者

@ManyToMany(cascade=CascadeType.ALL)

例如,或者您可以增加 CascadeType 的粒度。

还有一种替代方法是通过委托(delegate)方法处理集合。这样做的好处是您可以完全控制 addAuthor 方法,但对于使用您的实体的人来说不太直观。可以写成:

public void addAuthor(Author A) {
this.getAuthors().add(a);
a.addBook(this);
}

然后您需要实现 addBook。和级联变化。

你的选择也不错。您可以使用辅助类来实现此目的,但这会增加复杂性,因此请牢记这一点。

关于java - 在 JPA 中的两个相关实体中出现一些急切的 n 对 n 关系的更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5383189/

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