首页 > 解决方案 > JpaRepository.save() 方法如何在内部工作

问题描述

我有一个实体 - 工作流

@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()即在这些条件下将如何工作?它会在整个事物上运行更新语句还是只更新更改的对象?

标签: javahibernatespring-data-jpa

解决方案


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

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

关于如何save工作:

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

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

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


推荐阅读