Spring Data REST + JPA从OneToMany集合中删除[不是所有者方]

时间:2017-01-20 11:53:07

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

目前,在尝试更新集合(关系)时,我们遇到了Spring Data JPA + Spring Data RESTHibernateJPA实现)的问题(一个众所周知的问题)是一个不属于自己的一方。

映射如下:

@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 一侧的;但是如果您想要更新&#34;产品&#34;通过更新其变体集合并将PATCH请求发送到仅包含新集合的有效负载的https://localhost:8112/storefront/rest/product/21394435410197232(包含3个项目中的2个):

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

我没有例外或任何事情,但由于拥有方是另一方没有任何东西被保留,我再次得到旧的3 items

know我可以通过设置

来解决这个问题
@JoinColumn(name = "baseproduct_id", referencedColumnName = "id")

双方而不是在任何地方使用mappedBy,但是我听说有一个性能含义,我不确定它有多大(我们有100多个实体{{ 1}})我想知道通过@OneToMany听众还是有更好的解决方法吗?

1 个答案:

答案 0 :(得分:5)

this article中所述,您必须同步双向关联的两面,并且还要添加orphanRemoval和Cascade。

因此,您的映射变为:

@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);
}

要使remove方法正常工作,您需要实现equals和hashCode as explain in this article