jpa - OneToMany 中具有 CascadeType.ALL 的实体不存在子对象
问题描述
我正在使用提供给我们团队的第 3 方库,其中一个实体与自身相同类型的实体具有 OneToMany 关系。我已更改实体名称以使其保持匿名。
可能有一种更好的方法可以用这种类型的关系来注释实体,但由于它是由第 3 方提供的,因此我避免进行许多更改,以便与未来的补丁和更新兼容。
它使用 OpenJPA 2.4.0-ep2.0
@Entity
@Table(name = Person.TABLE_NAME)
public class Person {
private Long parentUid;
private List<Person> children = new ArrayList<>();
@OneToMany(targetEntity = Person.class, cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@ElementJoinColumn(name = "PARENT_UID")
@ElementForeignKey
@ElementDependent
public List<Person> getChildren() {
return this.children;
}
}
当我试图坚持一个有孩子的人时,只有主要实体被坚持,孩子们被忽略了。
但是,如果我将 fetch 属性更改为 FetchType.EAGER,它就可以工作(它同时保留父级和子级)。我的理解是 fetch 类型只影响加载,而不影响插入。任何想法为什么会发生?
此外,有没有办法让它工作,同时保持 fetch 类型为 FetchType.LAZY?
我尝试了以下方法(修改设置器):
protected void setChildren(final List<Person> children) {
if (Objects.nonNull(children)) {
for (Person child : children) {
child.setParentUid(parentUid);
}
this.childItems = children;
} else {
this.childItems = new ArrayList<>();
}
}
解决方案
问题出在子实体中,您应该在子实体中使用 @ManyToOne 注释。
将以下代码添加到 Person :
public class person {
.
.
@MantToOne(fetch=FetchType.LAZY)
@JoinClolumn(name="PARENT_UID")
private Person parent;
public void setParent(Person parent){
}
.
.
}
然后像这样修改 setChildren 代码:
protected void setChildren(final List<Person> children) {
if (Objects.nonNull(children)) {
for (Person child : children) {
child.setParent(this);
}
this.childItems = children;
} else {
this.childItems = new ArrayList<>();
}
}
重要的一点是始终获取类型必须在父子节点中同步。
推荐阅读
- javascript - 在字段中使用 renderCell 时,材质 UI 数据网格过滤器不起作用
- sql - OleDb.ExecuteNonQuery 总是返回 0
- python - 如何融化熊猫数据框?
- django - Django 在 fk_set 上注释 sum
- javascript - 在对象中获取 google sheet 行和列的二维值
- amazon-web-services - 无法访问 AWS Lambda 控制台并显示错误消息“您没有足够的权限。拒绝访问。'
- python - Python机器学习SGD分类错误
- wpf - 如何防止 Main 在 app.g.cs 中自动生成?
- android - 使用 Flow 在服务和片段之间“对话”
- flutter - 如何获取 github 工作树或项目结构