从OneToMany集合中删除Spring Data REST + JPA [不是所有者端] [英] Spring Data REST + JPA remove from OneToMany collection [not owner side]

查看:58
本文介绍了从OneToMany集合中删除Spring Data REST + JPA [不是所有者端]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,当尝试更新不是拥有方的集合(关系)时,Spring Data JPA + Spring Data REST(Hibernate作为JPA实现)存在一个问题(一个众所周知的问题). /p>

映射如下:

@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 方面,一切都,但是,如果您想通过更新其变体集合来更新产品"并发送PATCH请求包含以下内容的 https://localhost:8112/storefront/rest/product/21394435410197232 仅新的收藏(3件中有2件):

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

我没有例外或其他任何东西,但是由于拥有方是另一方,因此任何东西都不会保留,而我又得到了旧的3 items.

know我可以通过设置

来解决此问题

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

两侧上都没有使用mappedBy,但是我听说有一个性能隐含性,我不确定它有多大(我们有100多个具有@OneToMany的实体)而且我想知道是否可以通过@PreUpdate侦听器或其他更好的解决方法?

解决方案

您必须同步双向关联的两端,还必须添加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);
}

您需要实现 equals Variant子实体中的> hashCode 方法可以使addremove方法有效地工作.

Currently we have an issue (a well known one) with Spring Data JPA + Spring Data REST (Hibernate as JPA implementation) when trying to update the collection (relation) which is a not the owning side.

The mapping is the following:

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

and on the other variant side:

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

all is good on the Java side if you use Spring Data JPA only, however if you want to update the "product" by updating its collection of variants and send PATCH request to https://localhost:8112/storefront/rest/product/21394435410197232 containing the payload of the new collection only (having 2 out of the 3 items):

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

I get no exceptions or anything but since the owning side is the other side nothing is persisted and I got the old 3 items again.

I know that I can fix this by setting

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

on both sides and not use mappedBy anywhere, however I have heard there is a performance implication which I am not sure how big it is (we got 100+ entities having @OneToMany) and I wonder is there better workaround via @PreUpdate listener or something ?

解决方案

You have to synchronize both sides of the bidirectional association, and also add on orphanRemoval and Cascade.

So, your mapping becomes:

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

And the two add/remove methods:

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

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

You need to implement equals and hashCode methods in the Variant child entity for the add and remove methods to work effectively.

这篇关于从OneToMany集合中删除Spring Data REST + JPA [不是所有者端]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆