java - JPA/Hibernate OnetoMany 防止重复子代
问题描述
围绕这个主题有几个不同的问题已经有了答案,但据我所知,许多答案都是旧的,或者对我来说没有明确的意义。
假设我有一个Entity
/ Table
:
@Entity
@Table(name = "ParentTable")
public class Parent {
@Id
@GeneratedValue
private Integer id;
@OneToMany(cascade = CascadeType.ALL)
@NotNull
private List<Child> children;
public Parent(String childLabel){
this.children = new ArrayList<>();
this.children.add(new Child(childLabel));
}
// Get/Set/Constructors
}
然后Child
作为:
@Entity
public class Child {
@Id
@GeneratedValue
private Integer id;
@NotNull
private String label;
public Child(String label){
this.label = label;
}
// Get/Set/Constructors
}
然后我通过以下方式构建一些父母:
String childLabel = "child-label";
Parent a = new Parent(childLabel);
Parent b = new Parent(childLabel);
// Save both parents to a db
它在表中创建两个具有不同 ID 的子实例。我知道这是因为Child
正在创建不同的实例,然后分别保存。
但是我应该如何改变我的设计以确保只保存和引用两个相同孩子的一个实例?我尝试构建孩子然后给父母,但后来我得到一个主键错误。
解决方案
改变你的构造函数来取一个孩子:
public Parent(Child childLabel){
this.children = new ArrayList<>();
this.children.add(childLabel);
}
如果要强制 Child 上的标签具有唯一性,请更改 Child 中的列定义
@Column(unique=true, nullable=false)
private String label;
如果多个 Parent 需要引用同一个孩子,那么您可能需要使用 ManyToMany 类型引用而不是 One to Many。
推荐阅读
- web-services - 通过 SoapUI 调用 Webservice 时出错 - 从 SAP GUI 测试 Webservice ok
- java - 执行搜索时,自定义 FieldBridge 中添加的 Hibernate/Lucene 字段未知
- laravel - 结合 Laravel + Vue.js 得到错误(未找到模块:错误:无法解析 'C:\xampp\htdocs\todolist\resources\js' 中的 './vue/App')
- c# - 从列表中删除元素并在 C# 中返回新列表的最佳方法是什么
- react-native - 使用 react-native-community/datetimepicker,如何显示用户选择的时间,而不是从新日期开始?
- elasticsearch - JanElastic 搜索查询以获取特定月份和年份的结果
- math - 以数值方式查找一组多项式解的所有解
- typo3 - 如何使内容从家庭布局滑动到默认布局
- websocket - Apollo Client 3 graphql 订阅同时使用轮询和 websocket
- javascript - 从自动完成下拉列表中选择