更新时间:2023-02-05 13:58:05
当你在一个新的 Question
上调用 questionRepo.save()
时,Spring Data 会识别你'重新尝试保存新实体,并在内部调用 EntityManager.persist()
.
When you call questionRepo.save()
on a new Question
, Spring Data recognizes that you're trying to save a new entity, and invokes EntityManager.persist()
internally.
EntityManager.persist(entity)
使作为参数传递的实体持久.
但是,当您在现有 Question
上调用 questionRepo.save()
时,Spring Data 会在内部调用 EntityManager.merge()
.
However, when you call questionRepo.save()
on an existing Question
, Spring Data invokes EntityManager.merge()
internally.
EntityManager.merge(entity)
返回实体的永久副本.
问题是你调用 requestConfig.getNewOptions()
之前调用 questionRepo.save()
.在您描述的第一种情况下并不重要,因为分配给 question
的原始实例(即使用 Question question = new Question(...); 创建的实例)code>),以及使用
.forEach(o -> config.getOptions().add(o))
行添加到 Option
的子实例,成为持久化,并获得一个自动生成的 id.
The problem is that you call requestConfig.getNewOptions()
before calling questionRepo.save()
. It doesn't matter in the first case you've described, since the original instance assigned to question
(i.e. the one created using Question question = new Question(...);
), as well as the child instances added to Option
using the line .forEach(o -> config.getOptions().add(o))
, become persistent, and obtain an autogenerated id.
但是,在第二种情况下确实很重要,因为新的子实例使用 .forEach(o -> config.getOptions().add(o))
,不会持久化.相反,只有 questionRepo.save()
返回的 副本 引用的子实体实例(反过来返回 EntityManager.merge()
的结果代码>)是持久的.
However, it does matter in the second case, since the new child instances added to Option
using the line .forEach(o -> config.getOptions().add(o))
, do not become persistent. Instead, only the child entity instaces referenced by the copy returned by questionRepo.save()
(which in turn returns the result of EntityManager.merge()
) are persistent.
您应该在调用 questionRepo.save()
之后简单地构造 idMapping
映射 (使用 question.getConfig().getNewOptions()
).那应该处理这两种情况.
You should simply construct the idMapping
map after calling questionRepo.save()
(using question.getConfig().getNewOptions()
). That should handle both cases.