如何在 Spring Data JPA OneToMany 关系中定义 Update 的 SQL 执行顺序?

问题描述 投票:0回答:1

假设我的实体是这样定义的 -

@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);

这工作正常,所有更新都按预期保存到数据库中。我现在有以下问题 -

  1. JPA 如何决定先执行哪个更新查询?是先更新子表还是先更新父表?

  2. 是否可以自定义这些查询的执行顺序? (我希望首先更新子表,然后由于表上的数据完整性约束而仅更新父表。)

尝试更改代码的执行顺序,但没有用。

spring-boot hibernate spring-data-jpa spring-data hibernate-mapping
1个回答
0
投票

我认为您的代码正在一个事务中运行。在这种情况下,在事务结束时,Hibernate 会按特定顺序刷新更改。所有修改的实体都将按照加载到事务中的顺序在数据库中更新。在你的情况下,它是从父母到孩子的。但例如,如果您在代码开头添加 childRepository.findById(1) - 该子级将在父级之前加载,并且也将首先更新。

要强制 Hibernate 在父级之前更新子级,您可以在 

someRepository.flush();

之后添加

child.setName()
如果您想检查操作顺序 - 只需打开 

show-sql

属性并查看日志中的 SQL 语句即可。

© www.soinside.com 2019 - 2024. All rights reserved.