分离的实体通过额外的列得以保持多对多

时间:2018-10-30 16:21:32

标签: java hibernate jpa

我想用一个额外的列创建多对多关系。我配置了这个:

@Entity
public class Configuration extends AbstractEntity {

    @OneToMany(
            mappedBy = "configuration",
            cascade=CascadeType.ALL,
            orphanRemoval = true
    )
    @JsonIgnore
    private List<ConfigurationQuestion> configurationQuestions = new ArrayList<>();


    public void addQuestion(QuestionDTO question) {
        ConfigurationQuestion configurationQuestion = new ConfigurationQuestion(this,
                question.getQuestion(), question.getResponse());

        configurationQuestions.add(configurationQuestion);
    }

}

加入表格

@Entity
public class ConfigurationQuestion implements Serializable {
    @EmbeddedId
    private ConfigurationQuestionId id ;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("configurationId")
    private Configuration configuration;


    @ManyToOne(fetch = FetchType.EAGER)
    @MapsId("questionId")
    @JoinColumn(name="question_id")
    private Question question;

    private Integer response; 

    public ConfigurationQuestion(Configuration configuration, Question question,
                                 Integer response) {
        this.configuration = configuration;
        this.question = question;
        this.response = response;
        this.id = new ConfigurationQuestionId(configuration.getId(), question.getId());
    }

}

可嵌入的ID

@Embeddable
public class ConfigurationQuestionId implements Serializable {

    private Long configurationId;

    private Long questionId;
}

有问题,我没有任何映射,我想单向进行。我的问题是当我尝试保存这样的东西时。我想保存一个配置,它的问题只是id而不是整个对象,它是分开保存的。

在“问题”实体中,我没有任何映射,我想单向进行。我的问题是当我尝试保存这样的东西时。我想保存一个配置,该配置具有作为问题的ID,而不是整个对象,而是单独保存。

Configuration configuration = new Configuration();
Question question = new Question();
question.setId(1L);

configuration.addQuestion(new QuestionDTO(question, 1));

repository.save(configuration);

我收到以下错误。如果我从配置中删除Cascade.ALL,则不希望级联更改对Question实体的更改,而不会在连接表中插入任何内容。我可以在不查找问题的情况下做到这一点吗?

detached entity passed to persist: Question

1 个答案:

答案 0 :(得分:1)

如果您不想CascadeConfiguration实体更改为Question实体,则必须单独保存。 JPA提供者有权抱怨传递的实体仍然是分离的。它仍然只是一个普通的旧Java对象实例,JPA EntityManager对此一无所知。

在保存Question实体之前,请先尝试分别保存Configuration

如果数据库中已经有Question,请知道其ID,但是要避免完全获取它的ID,可以使用getReference()方法,该方法返回Entity的代理。 JPA提供者仍然需要一些开销来验证实例是否存在(如果实例不存在,它应该抛出EntityNotFoundException),但是应该更轻巧。

如果您使用的是Spring Data JpaRepository,则有一个类似的方法,笨拙地命名为getOne(),它实际上执行相同的操作(称为EntityManager.getReference())。