JPA更新一对多关系的列表

9

我有一个问题实体,其中包含另一个名为“Alternatives”的实体列表,如下所示:

public class Question {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "question", cascade = CascadeType.ALL)
    @JsonManagedReference
    private List<Alternative> alternativeList;
}

public class Alternative implements Serializable {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "questionId", nullable = false)
    @JsonBackReference
    private Question question;

}

我想更新一个已存在的问题条目,用一个新的备选列表来替换它。为此,我正在使用我的JpaDao元素的合并方法与新的问题对象进行调用:

@Repository
public class JpaQuestionDao implements QuestionDao {
    @PersistenceContext
    private EntityManager em;

    @Transactional
    public Question update(Question question) {
        return em.merge(question);
    }
}

然而,实际上这是合并了两个列表:一个已经存在于数据库中的和提供的新列表。对于非列表对象我使用merge方法没有问题,这就是为什么我一直在使用merge方法。

有没有另一种方法不是合并而只更新列表?

1个回答

13

首先使用EntityManager.find()检索问题对象,使它成为托管状态。由于alternativeList是延迟加载的,因此必须在集合对象上调用方法来获取它并将其也变为托管状态。任何对Question对象和列表的更新都将自动发送到数据库。

@Transactional
public Question update(Question question) {
    Question q = em.find(Question.class, question.getId());
    q.setAlternativeList(null);
    q.setAlternativeList(question.getAlternativeList());
    ...

    return q;
}

或者,您可以尝试在 @OneToMany 集合上使用 orphanRemoval=true。

@OneToMany(fetch = FetchType.LAZY, mappedBy = "question", cascade = CascadeType.ALL, orphanRemoval=true)
@JsonManagedReference
private List<Alternative> alternativeList;

仍然存在同样的问题:(我将altList设置为以下内容 q.setAlternativeList(question.getAlternativeList()); - Felipe Mosso
嗯,您想对列表做什么?我的意思是,当列表传输到DB时,您对其内容期望是什么? - Ish
例如,我在数据库中有项目1、2和3。然后我想调用更新方法,传递一个新的Question对象和一个新的Alternative列表,假设是1、2和5(而不是3)。但是,我得到的是一个Alternative列表,其中包含1、2、3、1、2和5。 - Felipe Mosso
尝试使用更新后的代码。我首先通过将其设置为null来删除了列表,然后更新了列表。或者,您可以尝试在@OneToMany注释中使用orphanRemoval属性。 - Ish
1
@Ish “对Question对象和列表的任何更新都将自动发送到DB。” 是错误的,Question是关联的反向侧。但是,orphanRemoval将起作用(在Alternative中,question不可为空,因此我认为OP的意图是删除未使用的Alternative)。 - Dragan Bozanovic
@Ish,我采纳了你关于orphanRemove的建议,幸运的是这正是我一对多关系中缺失的.. 不需要将列表设置为null等操作,只需设置孤立删除即可与原始代码一起使用。感谢你的帮助! - Felipe Mosso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接