假设我的实体是这样定义的 -
@Entity
class GrandParent {
@OneToMany(mappedBy = "grandParent", cascade = CascadeType.ALL)
private List<Parent> parents = new ArrayList()<>;
@Column
private String name;
...
}
@Entity
class Parent {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "grandparent_id", nullable = false)
private GrandParent grandParent;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> children = new ArrayList()<>;
@Column
private String name;
...
}
@Entity
class Child {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "child_id", nullable = false)
private Parent parent;
@Column
private String name;
...
}
现在我想更新我的子实体的名称。所以,我正在做以下事情 -
GrandParent grandParent = new GrandParent(); // Assume all values are present.
grandParent.getParents().forEach(parent -> {
parent.setName("New Parent Name");
parent.getChildren().forEach(child -> {
child.setName("New Child Name");
});
});
grandParentRepository.save(grandParent);
这工作正常,所有更新都按预期保存到数据库中。我现在有以下问题 -
JPA 如何决定先执行哪个更新查询?是先更新子表还是先更新父表?
是否可以自定义这些查询的执行顺序? (我希望首先更新子表,然后由于表上的数据完整性约束而仅更新父表。)
尝试更改代码的执行顺序,但没有用。
我认为您的代码正在一个事务中运行。在这种情况下,在事务结束时,Hibernate 会按特定顺序刷新更改。所有修改的实体都将按照加载到事务中的顺序在数据库中更新。在你的情况下,它是从父母到孩子的。但例如,如果您在代码开头添加 childRepository.findById(1)
- 该子级将在父级之前加载,并且也将首先更新。
someRepository.flush();
之后添加
child.setName()
。如果您想检查操作顺序 - 只需打开 show-sql