我正在使用spring数据jpa。我有一对多关系定义如下:
@OneToMany(mappedBy = "participant", cascade = CascadeType.ALL, orphanRemoval = true)
public List<SurveyResponse> getSurveyResponses() {
return surveyResponses;
}
我有一个方法,它收集surveyResponses的集合并替换具有匹配键的现有repsonses。不幸的是,当我使用它时,hibernate会删除除我正在添加的响应之外的所有响应。为什么会这样?
我从不直接保存回复,我只是将它们设置在集合中,让cascade完成剩下的工作。以下是替换的方法:
public void updateResponses(List<SurveyResponse> responses) {
for (SurveyResponse response : responses) {
response.setParticipant(this);
}
if (this.surveyResponses != null) {
Set<String> questionKeys = responses.stream()
.map(SurveyResponse::getQuestionKey)
.collect(Collectors.toSet());
this.surveyResponses.removeIf(
surveyResponse -> questionKeys.contains(surveyResponse.getQuestionKey()));
this.surveyResponses.addAll(responses);
} else this.surveyResponses = responses;
}
在addAll调用之后,PersistentBag混合了旧的(托管的)和新的(尚未保留的)响应。当我在参与者实体上调用save(spring data jpa crudRepository方法)时,将删除所有旧响应。为什么呢?
答案 0 :(得分:0)
这可能是您遇到问题的原因: http://assarconsulting.blogspot.com/2009/08/why-hibernate-does-delete-all-then-re.html
我建议将集合类型从List
替换为Set
,看看它是如何表现的。
答案 1 :(得分:0)
这个问题应该删除,因为它是我代码中其他地方的错误。我做了一个过于复杂的setter导致了这个问题。不鼓励用答案删除问题,所以我只是在这里回答我自己的问题。对于任何人的好奇心,这都是不好的人:
,
自我注意,setter用于休眠,而不是用于你自己的代码。如果你需要一个花哨的制定者,那就制定一个新的方法。