【问题标题】:Detached entity passed to persist many to many with extra column传递的分离实体通过额外的列保持多对多
【发布时间】:2018-10-30 16:21:32
【问题描述】:

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

@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);

我收到以下错误。我不想级联对 Question 实体的更改,如果我从 Configuration 中删除 Cascade.ALL 不会在连接表中插入任何内容。我可以在不查找问题的情况下执行此操作吗?

detached entity passed to persist: Question

【问题讨论】:

  • @K.Nicholas 这个答案甚至与 OP 的问题无关。
  • 同样的事情。 “我如何在 spring-data-jpa 中使用 ManyToMany 关联”。他想要一个单向的答案,而且还有更多。
  • 不,完全不同。您链接的答案是关于一个引用自身的实体。这只是在您知道它的主键 时添加对另一个不同 实体的外键引用,这样您就不想承担从数据库中查询实体的开销.
  • 你能告诉我如何避免因问题而触发数据库吗?

标签: java hibernate jpa


【解决方案1】:

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

尝试先单独保存Question,然后再保存Configuration 实体。

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

如果您使用的是 Spring Data JpaRepository,则有一个类似的方法,尴尬地命名为 getOne(),它的作用基本相同(它称为 EntityManager.getReference())。

【讨论】:

  • 我单独保存问题。但是,当我想保存配置时,我希望在 ConfigurationQuestion 问题中只有 id,例如示例。有一个 id = 1 的问题保存在数据库中。当我保存配置时,我想保存配置和来自 ConfigurationQuestion 的关系。
  • 这不是您在示例中所做的。您正在创建一个全新的Question 并将id 设置为1,而不设置其余字段。 JPA 无法知道您只希望它从Question 实体中获取id。你的型号不对。
  • 我可以指定不持久化问题,而只是将其添加到连接表中吗?
  • 我更新了答案,我认为这是你真正想做的。获取对现有Question 实体的引用,除非您确实需要,否则无需从数据库中实际检索它。
猜你喜欢
  • 1970-01-01
  • 2015-11-03
  • 2017-05-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多