如何使用额外的列管理多对多的关联而不会获得EntityAlreadyExist异常?

时间:2017-01-13 09:51:46

标签: java hibernate jpa

我在spring jpa中有很多额外的列(激活),我想编辑关联(添加/删除不同的链接)。

class Question
.....

@OneToMany(mappedBy = "question",cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.DETACH})
private Set<OutletQuestion> outletQuestions = new HashSet<>();
.....

class Outlet
@OneToMany(mappedBy = "outlet", cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.DETACH})
private Set<OutletQuestion> outletQuestions = new HashSet<>();
......

@Entity
@Table(name = "outlets_questions")
public class OutletQuestion implements Serializable {


@Id
@ManyToOne
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "outlet_id")
private Outlet outlet;

@Id
@ManyToOne
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "question_id")
private Question question;

@Column(name="activated")
private boolean activated;

public Outlet getOutlet() {
    return outlet;
}

public void setOutlet(Outlet outlet) {
    this.outlet = outlet;
}

public Question getQuestion() {
    return question;
}

public void setQuestion(Question question) {
    this.question = question;
}

public boolean isActivated() {
    return activated;
}

public void setActivated(boolean activated) {
    this.activated = activated;
}

}

我的代码用于编辑插座和问题之间的链接:

   public Question saveWithOutlets(QuestionWithOutletsRequest questionWithOutletsRequest) {
        Question question = questionRepository.findOne(questionWithOutletsRequest.getQuestionId());

        List<Outlet> outletsToLink = outletRepository.findAll(questionWithOutletsRequest.getOutletIds());

// remove all previous links   
 question.getOutletQuestions().removeAll(question.getOutletQuestions());
// insert new
        for (Outlet o : outletsToLink) {
            OutletQuestion oq = new OutletQuestion();
            oq.setActivated(true);
            oq.setOutlet(o);
            oq.setQuestion(question);
            question.getOutletQuestions().add(oq);
        }

        questionRepository.save(question);
        return question;
    }

我收到以下错误:

javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [tipps.core.domain.OutletQuestion#tipps.core.domain.OutletQuestion@7d5800b5]

1 个答案:

答案 0 :(得分:0)

OutletQuestion的ID是Outlet和Question之间的连接。您拨打questionRepository.save(question);时,数据库中所有旧的OutletQuestion尚未被删除。您只能从Set(question.getOutletQuestions().removeAll(question.getOutletQuestions());)中删除它们,但不能从数据库中删除它们。

如果您尝试再次添加相同的OutletQuestion,您将获得EntityExistsException。尝试从数据库中删除所有OutletQuestions,然后再添加新的OutletQuestions。