- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 JPA 中更改两个实体之间的 n 对 n 关系的最佳方法是什么。
让我用一个例子来解释:假设我有一个 Author
和一个 Book
实体,其中 Book
可以有各种 Author
和 Author
可以在各种 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/
我有一个案例,在大多数情况下,对象之间的关系是这样的,因此在关系上预先配置一个渴望(加入)的负载是有意义的。但是现在我遇到了一种情况,我真的不想完成急切的加载。 我是否应该从关系中删除连接负载并将所有
在我的 Grails 项目中,我有以下类: class A { static hasMany = [cs:C] } class B { static hasMany = [cs:C]
想象一下以下简化的 DI 模型: @ApplicationScoped public class A { private B b; @Inject public A(B b)
我使用 MapLoader 将数据从数据存储初始加载到 Hazelcast (InitialLoadMode = EAGER)。我需要从一个物化 View 中加载这些数据,该 View 是为了在加载过
我使用 Hibernate Envers 4.3.10.Final。我有以下两个 JPA 类: public class Factory { private int factoryID;
EJB 似乎被延迟加载 - 每当访问时。 但是,我想急切地初始化它们 - 即每当容器启动时。这是如何实现的(尤其是在 JBoss 中) This topic给出了一些提示,但不是很令人满意。 最佳答案
我是一名优秀的程序员,十分优秀!