在Spring Data Repository
接口中,定义了以下操作:
public T save(T entity);
...并且文档说明应用程序应该继续使用返回的实体。
我知道这个决定背后的reasoning,这是有道理的。我还可以看到,对于具有独立实体的简单模型,这非常适用。但是考虑到一个更复杂的JPA模型,它有很多@OneToMany
和@ManyToMany
个连接,会出现以下问题:
当加载的模型的所有其余部分仍然引用传递给save(...)
的旧模型时,应用程序应该如何使用返回的对象?此外,应用程序中可能还有包含旧实体的集合。 JVM不允许全局"交换"未保存的实体与保存的实体。
那么正确的使用模式是什么?任何最佳做法?到目前为止,我只遇到了不使用@OneToMany
或@ManyToMany
的玩具示例,因此不会遇到此问题。我确信很多聪明人都对此长期以来一直认真思考,但我不知道如何正确使用它。
答案 0 :(得分:1)
section 3.2.7.1 of the JPA specification介绍了merge
应如何运作的内容。简而言之,如果正在管理(现有)保存的实例,则只需将其保存在原位。如果没有,则将其复制到托管实例(可能不一定是不同的对象,因为规范不要求在这种情况下必须创建新实例),并且保存到其他托管实体的实例的所有引用也是已更新以引用托管实例。这当然要求从正在保存的实体中正确定义关系。
实际上,这并不包括将实体实例存储在非托管集合(例如static
集合)中的情况。这无论如何都是不可取的,因为持久化实体必须始终通过持久性提供程序机制加载(谁知道实体实例可能在持久性存储中发生了变化)。
由于我过去多年一直使用JPA并且从未遇到过问题,因此我相信上面引用的部分在所有场景中都能很好地工作(受JPA提供商按预期实现)。如果遇到问题,您应该尝试一些让您担心的案例并发布单独的问题。