Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA update list of one to many relationship

I have a Question entity with a list of another entity called Alternatives like this:

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;

}

Then I wanted to update an exiting Question entry with a new set of Alternative list. For this I'm calling merge method of my JpaDao element with the new Question object:

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

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

However, this is in fact merging the two lists: the one already in database and the new provided one. I haven't had any problem with such method when I have non-list objects, that's why I kept using merge method.

Is there an alternative method to not merge but only update a list?

like image 608
Felipe Mosso Avatar asked Oct 06 '15 21:10

Felipe Mosso


1 Answers

Retrieve the question object first using EntityManager.find(). Question object will become managed as a result. Since alternativeList is lazily loaded, you have to invoke a method on the collections object to fetch it and make it managed as well. Any updates to the Question object and to the list will be automatically sent to the DB.

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

    return q;
}

Alternatively, you can try using orphanRemoval=true on your @OneToMany collection

@OneToMany(fetch = FetchType.LAZY, mappedBy = "question", cascade = CascadeType.ALL, orphanRemoval=true)
@JsonManagedReference
private List<Alternative> alternativeList;
like image 120
Ish Avatar answered Oct 17 '22 12:10

Ish