【问题标题】:How JpaRepository.save() method work internallyJpaRepository.save() 方法如何在内部工作
【发布时间】:2019-12-20 07:36:51
【问题描述】:

我有一个实体 - 工作流

@Entity
Workflow {
    ...
    ...
    @OneToMany(mappedBy = "workflow", cascade = CascadeType.ALL)
    List<Tasks> tasks
    ...
}

另一个任务实体与

@Entity
Task {
    ...
    Status status;
    ...
    @ManyToOne
    @JoinColumn(name = "workflow_id")
    Workflow workflow
    ...
}

两个实体都定义了JpaRepository

WorkflowRepo extends JpaRepository<Workflow, Id>
TaskRepos extends JpaRepository<Task, Id>

现在,更新Task的状态,哪种方法有效?

workFlowRepo.save(workflow) // saving the whole workflow object which internally updates task also 

或者

tasRepo.save(task) // saves only task object in repo.

上述两种技术之间是否存在任何主要的性能差异。

JpaRepoitory.save() 在这些条件下如何工作? 它会在整个事物上运行更新语句还是只更新更改的对象?

【问题讨论】:

    标签: java hibernate spring-data-jpa


    【解决方案1】:

    由于您没有级联注释,因此您必须保存task

    如果您有适当的级联注释,则性能差异取决于大量因素,例如实体的精确映射、实体的状态和底层 EntityManager 的状态。 一般来说,与实际保存实体所需的不可避免的时间相比,它可以忽略不计。

    关于save 的工作原理:

    save 操作在底层EntityManager 上执行merge。 这本身不执行任何 SQL,而只是返回实体的托管版本。 如果尚未将其加载到EntityManager 中,它可能会执行此操作,或者可能会将实体标识为新实体并使其成为托管实体。 然后它可能必须执行插入语句或选择才能获得 id。

    如果保存没有作为上述副作用发生,它只会在EntityManager刷新时发生。 这通常发生在事务结束时,但也可能发生在查询执行之前或明确要求时。

    注意:看起来你想要一个双向关系,但实际上你有两个独立的关系。一个从WorkflowTask,一个从TaskWorkflow

    【讨论】:

    • 嗨 Jenes,Cascade 用于任务,我确实有双向关系,我在复制时错过了。对不起
    • 现在,由于我有级联和双向关系,更新其中一个任务状态的方法将是有效的。保存整个工作流程或仅保存该任务的状态。
    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2010-10-25
    相关资源
    最近更新 更多