【问题标题】:Spring Data REST + JPA remove from OneToMany collection [not owner side]从 OneToMany 集合中删除 Spring Data REST + JPA [不是所有者方]
【发布时间】:2017-06-05 09:48:26
【问题描述】:

目前我们在尝试更新不是拥有方的集合(关系)时遇到Spring Data JPA + Spring Data RESTHibernate 作为JPA 实现)的问题(一个众所周知的问题)。

映射如下:

@Entity(name = Product.NAME)
public class Product {
...
@OneToMany(mappedBy = "baseProduct", fetch = FetchType.LAZY, targetEntity = Variant.class)
List<Variant> getVariants() {
... 

在另一个变体方面:

@Entity(name = Variant.NAME)
public class Variant extends Product {
...
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Product.class)
@JoinColumn(name = "baseproduct_id", referencedColumnName = "id")
Product getBaseProduct() {
...
}

如果您仅使用 Spring Data JPA,则 Java 方面的一切都是 good,但是如果您想通过更新其变体集合来更新“产品”并发送PATCHhttps://localhost:8112/storefront/rest/product/21394435410197232 的请求仅包含新集合的有效负载(3 项中有 2 项):

{"variants":["22801810293768080","22801810293768096"]}

我没有得到任何例外或任何东西,但由于拥有方是另一方,所以没有任何东西被持久化,我又得到了旧的 3 items

know我可以通过设置来解决这个问题

@JoinColumn(name = "baseproduct_id", referencedColumnName = "id")

双方上,不要在任何地方使用mappedBy,但是我听说有一个性能影响,我不确定它有多大(我们有100多个具有@OneToMany的实体)我想知道通过@PreUpdate listener 或其他方式是否有更好的解决方法?

【问题讨论】:

  • 您找到答案了吗?我有这个确切的问题,我如何从非所有者方面更新关联?
  • 如下所述,如果它是双向的,那么您需要更新双方。

标签: java spring hibernate jpa spring-data-jpa


【解决方案1】:

你必须同步双向关联的双方,还要加上orphanRemovalCascade

因此,您的映射变为:

@OneToMany(
    mappedBy = "baseProduct", 
    fetch = FetchType.LAZY, 
    targetEntity = Variant.class
    cascade = CascadeType.ALL, 
    orphanRemoval = true)
List<Variant> getVariants() {

还有两个添加/删除方法:

public void addVariant(Variant variant) {
    getVariants().add(variant);
    variant.setBaseProuct(this);
}

public void removeVariant(Variant variant) {
    variant.setBaseProuct(null);
    this.getVariants().remove(variant);
}

您需要在Variant 子实体中实现equalshashCode 方法,以使addremove 方法有效地工作。

【讨论】:

  • 谢谢,但是目前我不想删除孤儿我只想删除“连接”而不是删除任何一侧:) 另外我不是级联的忠实粉丝也许我遗漏了一些东西,但是 Spring Data Rest 会以某种方式调用 addXXX 和 removeXXX 方法?
  • 那你有错误的映射,因为你没有指定@JoinTable。如果您有一个连接表,那么映射它的最佳方法是将连接表映射为具有 2 个@ManyToOne associations 的中间实体。我的书中有一个例子,High-Performance Java Persistence
  • @VladMihalcea 有了这个解决方案,我得到 java.util.ConcurrentModificationException: null。我有一个元素列表,我必须为每个列表项调用 removeVariant 方法......如何解决这个问题?我尝试使用 iterator.remove() 但到目前为止没有成功:(
猜你喜欢
  • 2016-08-17
  • 1970-01-01
  • 2017-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
相关资源
最近更新 更多