Java 在JPA中的两个相关实体中,都会出现在某些急切的n-to-n关系中进行更新的情况
改变JPA中两个实体之间n对n关系的最佳方式是什么 让我用一个例子来解释:假设我有一个Java 在JPA中的两个相关实体中,都会出现在某些急切的n-to-n关系中进行更新的情况,java,jpa,persistence,many-to-many,eager-loading,Java,Jpa,Persistence,Many To Many,Eager Loading,改变JPA中两个实体之间n对n关系的最佳方式是什么 让我用一个例子来解释:假设我有一个作者和一个书实体,其中书可以有各种作者s,而作者可以写各种书s。此模型表示为n对n的渴望关系: @Entity public class Author { @ManyToMany(fetch=FetchType.EAGER) private List<Book> books; // ... } 或者从作者的书籍中删除书籍: public class SomeOtherSer
作者
和一个书
实体,其中书
可以有各种作者
s,而作者
可以写各种书
s。此模型表示为n对n的渴望关系:
@Entity
public class Author {
@ManyToMany(fetch=FetchType.EAGER)
private List<Book> books;
// ...
}
或者从作者的书籍中删除书籍
:
public class SomeOtherService {
public void removeBook(Author author, Book book) {
author.getBooks().remove(book);
em.persist(author);
}
}
但是,我希望在不更新的实体中注册更新。当我调用addAuthor()
时,我希望更新的书籍也会出现在作者的书籍列表中。我想在调用removeBook()
时,将作者
从书籍
的作者列表中删除
如果代码与上述代码相同,则不会发生。我当前的解决方案是在两个实体中执行反对应操作,大致如下所示:
public class SomeService {
public void addAuthor(Book book, Author author) {
book.getAuthors().add(author);
author.getBooks().add(book);
em.persist(book);
em.persist(author);
}
}
不过,对我来说,这似乎是一个蹩脚的解决方案。所以,我的问题是:有没有更好的方法
提前感谢?查看@PreXXXX和@PostXXXX注释。根据您正在使用的数据库,您最好进入并编写自己的触发器
如果你正在寻找最不可知论的方法,那么你所提出的解决方案应该会奏效
编辑:
另一种方法是保存触发器代码,并在CRUD之后将其作为本机SQL运行(假设您在测试中创建并删除)。对我来说,这并不是一个真正的跛脚解决方案,因为它对正在发生的事情非常明确,一个优点是您有一个非常明确的代码。然而,如果对你来说,这是过于明确,那么你有几个选择
正如Jay所建议的那样,您可以编写一个@PreUpdate回调方法来执行以下操作:
author.getBooks().add(book);
但是,要使其起作用,您必须使用@manytomy注释的cascade属性将更改级联到作者
@ManyToMany(cascade=CascadeType.ALL)
例如,也可以增加级联类型的粒度
还有一种替代方法是通过委托方法处理集合。
这样做的好处是,您可以完全控制addAuthor方法,但对使用您的实体的人来说,直观性较差。
它可以写为:
public void addAuthor(Author A) {
this.getAuthors().add(a);
a.addBook(this);
}
然后需要实现addBook。和级联变化
你的选择也不错。您可以使用helper类来实现这一点,但这会增加复杂性,因此在您的头脑中。维护双向关系状态可能是一项挑战。最后两者都
book.getAuthors().add(author);
author.getBooks().add(book);
需要打电话
在我工作的地方,我们使用aspectJ和一些内部元数据来处理关联双方的设置。对于小项目来说,这有点过头了,而且你做的方式很好。文森特·帕丁顿曾经写过一篇博文,我相信你会对此感兴趣。本质上,他建议在关系中的每个伙伴上都有两个关系添加方法:一个是内部(可能是包范围内的)方法,它只向集合添加一个项,另一个是外部方法,它调用两个伙伴上的内部方法。同样的模式也可以应用于删除方法。很抱歉我不知道,但我不知道DB中的触发器在这里有什么用处。你能解释一下吗?
public void addAuthor(Author A) {
this.getAuthors().add(a);
a.addBook(this);
}
book.getAuthors().add(author);
author.getBooks().add(book);