繁体   English   中英

Spring 数据 JPA 保存时通过 id 进行多次选择

[英]Spring Data JPA make many selects by id when save

我有这个模型:

数据模型:

@Table(name = "data_model")
public class DataModel {

    @Id
    @GeneratedValue
    @Column(name = "model_id")
    private Integer id;

    @OneToMany(orphanRemoval = true, mappedBy = "dataModel", cascade = {CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE})
    private List<OutputField> outputFields;

    @OneToMany(orphanRemoval = true, mappedBy = "dataModel", cascade = {CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE})
    private List<IncrementField> incrementFields;

}

输出字段:

@Table(name = "data_model_output_field")
public class OutputField {

    @Id
    @GeneratedValue
    @Column(name = "output_field_id")
    private Integer id;

    @ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
    @JoinColumn(name = "model_id")
    private DataModel dataModel;

}

增量字段:

@Entity
@Table(name = "data_model_increment_field")
public class IncrementField {

    @Id
    @GeneratedValue
    @Column(name = "increment_field_id")
    private Integer id;
    
    @ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
    @JoinColumn(name = "model_id")
    private DataModel dataModel;
}

我有服务方法:

@Transactional
public void createOrUpdate(DataModel dataModel) {
    DataModel savedDataModel = dataModelRepository.save(dataModel);
}

当我尝试保存实体时,在日志中我看到许多 select 查询:

Name:test-ds, Connection:9, Time:0, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["
    select
        outputfiel0_.model_id as model_id8_4_0_
    from
        data_model_output_field outputfiel0_ 
    where
        outputfiel0_.output_field_id=1"]


Name:test-ds, Connection:9, Time:0, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["
    select
        outputfiel0_.model_id as model_id8_4_0_
    from
        data_model_output_field outputfiel0_ 
    where
        outputfiel0_.output_field_id=2"]


Name:test-ds, Connection:9, Time:0, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["
    select
        outputfiel0_.model_id as model_id8_4_0_
    from
        data_model_output_field outputfiel0_ 
    where
        outputfiel0_.output_field_id=3"]


Name:test-ds, Connection:9, Time:0, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["
    select
        outputfiel0_.model_id as model_id8_4_0_
    from
        data_model_output_field outputfiel0_ 
    where
        outputfiel0_.output_field_id=4"]

Name:test-ds, Connection:9, Time:0, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["
    select
        outputfiel0_.model_id as model_id8_4_0_
    from
        data_model_output_field outputfiel0_ 
    where
        outputfiel0_.model_id=2"]

它通过 id 获取每个字段。 但是他为什么这样做,他可以立即通过model_id拿起列表?

此外,在日志的最后,他做到了。 为什么他需要以前的查询呢?

更新

复制的简单示例: https://github.com/eaxdev/simple-web-app

那是因为save方法使用EntityManager.merge刷新更改,而您正在使用 MERGE 级联。 我不知道您要在此处保存什么样的 object 图,但似乎outputFields集合有 4 个条目首先经历 MERGE 级联,即 Hibernate 选择当前 Z9ED39E2EA9314586B6EZA985 的这些对象。变化。 接下来,Hibernate 尝试刷新DataModel#outputFields关系的更改,即外键,它需要查询所有对象,以便它知道要删除什么(我认为这是由于孤立删除而需要的)。

在我看来, OutputFieldIncrementFieldDataModel有组合关系,那么为什么不把 model 当作@Embeddable呢? 这样,Hibernate 可以更有效地管理关联。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM