在 this question 提交保存 entity2
和 entity3
实例的事务中,每个实例都持有对 Entity1 (entity1) 实例的引用,导致 entity1 的两条记录出现在数据库中(因为在保存每个实例时会保存引用)。
如果我有 2 个 Spring Data Repositories - Entity2Repository
和 Entity3Repository
并且我执行以下操作将导致数据库中包含实体 1 的 2 个实例:
Entity1 entity1 = new Entity1();
entity1.name = "Name1";
entity1.value = "Value1";
Entity2 entity2 = new Entity2();
entity2.name = "Name2";
entity2.value = "Value2";
entity2.setEntity1(entity1);
Entity3 entity3 = new Entity3();
entity3.name = "Name3";
entity3.value = "Value3";
entity3.setEntity1(entity1);
Entity2Repository.save(entity2);
Entity3Repository.save(entity3);
最佳答案
简答
它将正常工作(仅生成 entity1
的一条记录)。
长答案
示例代码执行的实际结果取决于测试方法上是否存在 @Transactional 注释。
Entity2Repository.save(entity2);
Entity3Repository.save(entity3);
这些调用将调用 SimpleJpaRepository#save() 方法,它是 @Transactional 本身。
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
此外,如您所见,您不应该担心持久/合并调用 - 如果它是一个新实体,则会调用
persist()
。 isNew()
检查非常简单(参见 AbstractPersistable 源代码):public boolean isNew() {
return null == getId();
}
没有@Transactional
将有两个事务 - 每个
save()
调用一个。entity1
, entity2
和 entity3
是 TRANSIENT 现在是 Entity2Repository.save(entity2)
被调用 persist()
为 entity2
调用,因为它是新实体 persist()
级联到 entity1
entity1
和 entity2
现在是 PERSISTENT ,它们附加到当前 session
entity1
和 entity2
是 DETACHED 现在是 Entity3Repository.save(entity3)
被调用 persist()
为 entity3
调用,因为它是新实体 persist()
级联到 entity1
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist
被抛出 entity1
和 entity2
条目保存在数据库中。与@Transactional
默认情况下@Transactional 传播是
REQUIRED
- 只有一个事务。entity1
, entity2
和 entity3
是 TRANSIENT 现在是 Entity2Repository.save(entity2)
被调用 persist()
为 entity2
调用,因为它是新实体 persist()
级联到 entity1
entity1
和 entity2
现在是 PERSISTENT ,它们附加到当前 session Entity3Repository.save(entity3)
被调用 persist()
为 entity3
调用,因为它是新实体 persist()
级联到 entity1
,在一级缓存中找到的管理实体 entity3
现在是 PERSISTENT ,它附加到当前 session entity1
、 entity2
和 entity3
条目保存在数据库中。关于java - 将 CascadeType.MERGE 与 Spring Data Repositories 一起使用的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46537455/