JPA 映射注释错误 org.hibernate.MappingException: 外键必须与引用的主键具有相同的列数

JPA mapping annotation error org.hibernate.MappingException: Foreign key must have same number of columns as the referenced primary key

我无法使用 JPA 批注正确映射数据库表。

Tables Subject and Place 是 ManyToMany 通过 JoinTable.

Subject.java

@Entity
@Table(name = "SUBJECT")
public class Subject implements Serializable {
    @Id
    @Column(name = "SID")
    private Integer sid;

    @Column(name = "NAME")
    private String name;

    // getters and setters
}

SubjectPlace.java

@Entity
@Table(name = "SUBJECT_PLACE")
public class SubjectPlace implements Serializable {
    @Id
    @Column(name = "SPID")
    private Integer spid;

    @ManyToOne
    @JoinColumn(name = "SUB_KEY") //Subject FK
    private Subject subject;

    @ManyToOne
    @JoinColumn(name = "PLC_KEY") //Place FK
    private Place place;

    // getters and setters
}

Place.java

@Entity
@Table(name = "PLACE")
public class Place implements Serializable {
    @Id
    @Column(name = "PID")
    private Integer pid;

    @Column(name = "NAME")
    private String name;

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
        @JoinTable(name = "SUBJECT_PLACE",
            joinColumns = { @JoinColumn(name = "PLC_KEY", nullable = false, updatable = false) },
            inverseJoinColumns = { @JoinColumn(name = "SUB_KEY", nullable = false, updatable = false) })
    private Set<Subject> subjects;

    // getters and setters
}

但是我需要 link Person with Subject 在选定的地方。我的意思是每个 Place 都有自己的 Subject 集合。并且一个人有 link 到居住在特定地点的主题。

像这样:

Subject (M) -- (M) Place 通过 JoinTable Subject (1) -- (M) Subject_Place (M) -- (1) Place

Person (M) -- (M) Subject_Place 通过 JoinTable Person (1) -- (M) Person_Subject_Place (M) -- (1) Subject_Place

Person.java

@Entity
@Table(name = "PERSON")
public class Person implements Serializable {
    @Id
    @Column(name = "PRSID")
    private Integer prsid;

    @Column(name = "NAME")
    private String name;

    // How to annotate this code?
    // I experience problem in this part of code
    @OneToMany
    @JoinColumn(name="SPID_KEY") 
    private List<SubjectPlace> subjectPlaces;

    // getters and setters
}

人SubjectPlace.java

@Entity
@Table(name = "PERSON_SUBJECT_PLACE")
public class PersonSubjectPlace implements Serializable {
    @Id
    @Column(name = "PSPID") // Person_Subject_Place ID
    private Integer pspid;

    @ManyToOne
    @JoinColumn(name = "PER_KEY") //Person FK
    private Person person;

    // How to annotate this code?
    // I experience problem in this part of code
    @ManyToOne
    @JoinColumn(name = "SPID_KEY") //Subject_Place FK
    private SubjectPlace subjectPlace;

    // getters and setters
}

当我尝试获取人物及其主题时,我收到此错误: Caused by: org.hibernate.MappingException: Foreign key (FK2C3B79384AABC975:PERSON_SUBJECT_PLACE [SPID_KEY])) must have same number of columns as the referenced primary key (SUBJECT_PLACE [PLC_KEY,SUB_KEY])

什么,我应该如何映射?

您应该删除 @Joincolumn 注释并将 mappedBy 变量添加到 @OneToMany 注释。

@OneToMany(mappedBy = "spid")

你应该在 SubjectPlace 中有一个变量,它有一个 Person 你应该在其中放置 @JoinColumn 注释

在你的 OneToMany 映射中你不需要指定外键,你只需要使用 mappedBy 属性 来引用你的映射对象,你可以了解更多它在 OneToMany Mapping Documentation 中,这是映射 PersonPersonSubjectPlace 实体所需的内容:

在你身上class:

@OneToMany(mappedBy="person")
private List<PersonSubjectPlace> personsubjectPlaces;

在你的 PersonSubjectPlace class:

@ManyToOne
@JoinColumn(name="PRSID") //Specify the primary key of Person
private Person person;

有关 JoinColumnmappedBy 之间区别的更多信息,您可以查看 this answer

编辑:

对于SubjectPlacePersonSubjectPlace之间的映射:

在您的 SubjectPlace class:

@OneToMany(mappedBy="subjectPlace")
private List<PersonSubjectPlace> personsubjectPlaces;

在你的 PersonSubjectPlace class:

@ManyToOne
@JoinColumn(name="SPID") //Specify the primary key of SubjectPerson
private SubjectPlace subjectPlace;

注:

映射那些 classes 的最佳方法是在 PersonSubjectPlace 之间使用 @JoinTable,看看 this @JoinTable example,因为 PersonSubjectPlace 实际上是 PersonSubjectPlace 之间的关联实体。