1

是否可以在 Section.class 中进行级联保存?我创建 Section 对象并添加没有 id 的新问题。当我尝试保存它时,我收到错误:

org.postgresql.util.PSQLException:错误:在表“question_to_section”上插入或更新违反了外键约束“fk_2br9f09ok965403a9rv5y2n10”详细信息:表“问题”中不存在键(question_id)=(0)。

我也尝试使用@Embedded 注释,但没有成功。

部分类:

@Table(name = "section")
@Entity(name = "section")
public class Section implements Serializable{   

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id",    unique = true, nullable = false)
    @JsonProperty
    long id;    

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "section")
    Set<QuestionToSection> questions = new HashSet<QuestionToSection>(0);
    ...
}

问题到部分类

@Entity(name = "question_to_section")
@Table(name = "question_to_section")
@IdClass(QuestionSectionId.class)
public class QuestionToSection implements Serializable {

    @Id
    long sectionId;

    @Id
    long questionId;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "sectionId", nullable = false, updatable = false, insertable = false, referencedColumnName = "id")
    Section section;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL )
    @JoinColumn(name = "questionId", nullable = false, updatable = false, insertable = false, referencedColumnName = "id")
    Question question;
    ...
}

QuestionSectionId

public class QuestionSectionId implements Serializable {

    long questionId;
    long sectionId; 

}
4

2 回答 2

0

不必将数据库中的每个表都映射到一个实体。特别是,纯连接表通常最好不要映射为实体。对于多对多关系,例如:

@Table(name = "section")
public class Section implements Serializable{   

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    @JsonProperty
    long id;    

    // Note: probably do not want to cascade REMOVE operations
    @ManyToMany(fetch = FetchType.LAZY,
        cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH},
        mappedBy = "sections")
    @JoinTable(
        name = "question_to_section"
        joinColumns =
            @JoinColumn(name="sectionId", referencedColumnName="ID"),
        inverseJoinColumns=
            @JoinColumn(name="questionId", referencedColumnName="ID")
    )
    Set<Question> questions = new HashSet<Question>(0);
    ...
}

这假定了双向关系,在 entity 中具有相应的注释Question;对于单向,mappedBy删除ManyToMany. 无论哪种方式,这都使您question_to_entity无需直接管理表,并减少系统中离散实体的数量。


另一方面,如果您需要一个真正的 QuestionToSection弱实体——,如果实例具有它们关联的问题和部分以外的属性——那么你确实遇到了级联持久性的问题。您尝试将多个实体属性映射到数据库中的同一列,从而为不一致提供了机会。

如果所涉及的和实体之一或两者都是新的,存在不一致之处,因此它还没有 ID。JPA 无法知道它应该从关联和实体的 ID 中设置 id 字段。当他们收到自动生成的 ID 时,与他们关联的实体将变得不一致。QuestionSectionQuestionToSectionQuestionSectionQuestionToSection

可以想象,您可以通过设置来解决该问题@Access(AccessType = PROPERTY)QuestionToSection并使用持久属性访问器方法玩游戏,但这有点讨厌。如果你确实需要一个弱实体,那么最好不要尝试级联PERSIST操作,尽管你可以级联其他操作。事实上,在这种情况下,您可能确实希望将REMOVE操作级联弱实体,而不是它到其他关联实体。

于 2017-01-24T16:02:48.290 回答
0

您应该从类中的insertable = false两者中删除。您正在覆盖级联插入,因此如果它们不存在,JPA 将不会插入。只需从注释中删除可插入的内容,即可解决您的问题。@JoinColumnQuestionToSection

于 2017-01-24T15:08:37.203 回答