spring-data-jpa - Spring Data Rest - 无法使用 PUT 或 PATCH 更新嵌套对象
问题描述
我在 Attribute 和 AttributeGroup 之间有多对多的关系。AttributeGroup 包含许多属性,这些属性可以是多个 AttributeGroup 的子级。虽然 Attribute 是 AttributeGroup 的子关系,但它始终是在自己的存储库中创建的,即,希望在 AttributeGroup 之前创建 Attribute,并且在创建 AttributeGroup 期间添加子关系时。使用属性 repo,我可以执行所有 CRUD 操作,并使用 attributeGroup repo,成功处理 CRUD 操作。在 AttributeGroup 创建期间,与 Attribute 的关系也按预期工作。接下来,如果我想更改关系,即删除现有属性和/或添加另一个属性,它不起作用。我读到更新嵌套对象 PATCH 有效,但 PATCH 抛出异常
java.lang.IllegalArgumentException: Can not set java.lang.Long field Attribute.id to AttributeGroup
请让我知道这个实现有什么问题。
属性组.java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
public class AttributeGroup implements Serializable {
private static final long serialVersionUID = -8264102706248686536L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String name;
String displayName;
@NotNull
@Size(min = 1)
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.REFRESH})
List<Attribute> attributes;
}
属性.java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
public class Attribute implements Serializable {
private static final long serialVersionUID = 8806808817130076030L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String name;
String value;
AttributeType attributeType;
ArrayList<String> values;
@ManyToMany(mappedBy = "attributes")
@ToString.Exclude
List<AttributeGroup> attributeGroups;
}
属性类型.java
public enum AttributeType {
TEXT("Text Only");
private final String attributeType;
AttributeType(String productType) {
this.attributeType = productType;
}
}
解决方案
在bidirectinoal
关系中,您需要同步关系的双方才能删除实体。
AttributeGroup
是关系的所有者。所以,它必须有一个像下面这样的方法:
public void removeAttribute(Attribute attribute){
if(attributes.contains(attribute)){
attributes.remove(attribute);
attribute.getAttributeGroups().remove(this);
}
}
此外,在Attribute
课堂上你应该有:
@PreRemove
void removeAttributeFromAttributeGroups(){
for (AttributeGroup attributeGroup : attributesGroups) {
attributeGroup.removeAttribute(this);
}
}
相同的程序适用于Add
操作。
推荐阅读
- ionic-framework - Ionic 3 google maps 链接在头部生成
- python - 有没有办法根据python中的另一个def再次附加附加消息?
- .net-core - IdentityServer4 通过 id_token 或 access_token 登录
- php - 如果 url 包含特定的单词/PHP,则隐藏 404 错误
- javascript - 如果当前时间在 json 数据的开始时间和结束时间之间,则显示数据
- php - WooCommerce 挂钩中的产品变体和父变量产品对象
- php - PHP:如何将日期时间字符串拆分为两个新变量?
- spring-boot - 登录认证成功后 Spring Security 不重定向
- pyspark - 如何创建 python 库以及如何在 palantir Foundry 中导入它
- reactjs - React Final Form and Material UI,在选择特定单选按钮时禁用元素