【问题标题】:How to correctly use Spring Data Repository#save()?如何正确使用 Spring Data Repository#save()?
【发布时间】:2015-05-26 15:25:06
【问题描述】:

在Spring DataRepository接口中,定义了如下操作:

public T save(T entity);

...文档声明应用程序应继续使用返回的实体。

我知道这个决定背后的reasoning,这是有道理的。我还可以看到,这对于具有独立实体的简单模型非常有效。但考虑到具有大量@OneToMany@ManyToMany 连接的更复杂的JPA 模型,就会出现以下问题:

当所有加载的模型的其余部分仍然引用传递给save(...) 的旧模型时,应用程序应该如何使用返回的对象?此外,应用程序中可能存在仍包含旧实体的集合。 JVM 不允许全局“交换”未保存的实体与已保存的实体。

那么正确的使用模式是什么?有什么最佳实践吗?到目前为止,我只遇到过不使用@OneToMany@ManyToMany 的玩具示例,因此不会遇到这个问题。我敢肯定,很多聪明人对此深思熟虑,但我不知道如何正确使用它。

【问题讨论】:

    标签: spring spring-data spring-data-jpa


    【解决方案1】:

    这在section 3.2.7.1 of the JPA specification 中有所介绍,描述了merge 应该如何工作。简而言之,如果要保存的实例是托管的(现有的),它只是就地保存。如果不是,则将其复制到托管实例(可能不一定是不同的对象,因为规范不要求在这种情况下必须创建新实例)并且来自实例的所有引用都保存到其他托管实体更新为引用托管实例。这当然需要从正在保存的实体中正确定义关系。

    确实,这不包括将实体实例存储在非托管集合(例如static 集合)中的情况。这无论如何都是不可取的,因为必须始终通过持久性提供程序机制加载持久化实体(谁知道实体实例可能在持久化存储中发生了变化)。

    由于我过去多年一直在使用 JPA 并且从未遇到过问题,因此我相信我上面引用的部分在所有情况下都能很好地工作(取决于 JPA 提供者按预期实施它)。您应该尝试一些您担心的案例,并在遇到问题时单独提出问题。

    【讨论】:

      猜你喜欢
      • 2019-05-28
      • 2017-11-23
      • 2018-01-09
      • 2023-03-09
      • 2012-01-27
      • 2014-02-16
      • 2017-11-28
      • 2020-11-17
      相关资源
      最近更新 更多