JPA替换集合中的一个元素

时间:2017-10-04 19:16:54

标签: java spring hibernate jpa spring-data-jpa

我正在使用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方法)时,将删除所有旧响应。为什么呢?

2 个答案:

答案 0 :(得分:0)

这可能是您遇到问题的原因: http://assarconsulting.blogspot.com/2009/08/why-hibernate-does-delete-all-then-re.html

我建议将集合类型从List替换为Set,看看它是如何表现的。

答案 1 :(得分:0)

这个问题应该删除,因为它是我代码中其他地方的错误。我做了一个过于复杂的setter导致了这个问题。不鼓励用答案删除问题,所以我只是在这里回答我自己的问题。对于任何人的好奇心,这都是不好的人:

,

自我注意,setter用于休眠,而不是用于你自己的代码。如果你需要一个花哨的制定者,那就制定一个新的方法。