使用@javax.persistence.JoinColumns
(注意末尾的“s” )注释来定义复合外键的映射。您应该具有以下内容:
@JoinTable(name="mapping_table",
joinColumns={@JoinColumn(name="request_id")},
inverseJoinColumns={@JoinColumns({
@JoinColumn(name="requester_id"),
@JoinColumn(name="requester_id")})
}
)
我认为它应该工作。
对不起第一个答案:我认为@JoinColumns
注释不能在一个内部使用@JoinTable
。所以我决定再调查一下。
我创建了 2 个表:
Student
具有由名字和姓氏组成的嵌入式 id的实体类。
Teacher
具有自动长 id 和Set<Student>
as 属性的实体类。
我用关系映射了Set
属性@ManyToMany
,并在属性中使用了一组@JoinColumn
注释inverseJoinColumns
:
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(
name="STUDENT_TEACHER",
joinColumns=@JoinColumn(name="TEACHER_ID"),
inverseJoinColumns={
@JoinColumn(name="STUDENT_FIRSTNAME"),
@JoinColumn(name="STUDENT_LASTNAME")
}
)
private Set<Student> students = new HashSet<Student>();
我做了一些测试来检查一切是否正常,我没有问题(获取类型只是为了有更简单的测试用例)。我在这里添加了我正在使用的 2 个实体的代码:
学生.java
@Entity
public class Student {
@EmbeddedId
private Id id = new Id();
public Id getId() {
return id;
}
public void setId(Id id) {
this.id = id;
}
@Embeddable
public static class Id implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name="FIRST_NAME")
private String studentFirstname;
@Column(name="LAST_NAME")
private String studentLastname;
public Id() { }
public Id(String firstname, String lastname) {
studentFirstname = firstname;
studentLastname = lastname;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Id) {
Id id = (Id)obj;
return studentFirstname.equals(id.studentFirstname) &&
studentLastname.equals(id.studentLastname);
}
return false;
}
@Override
public int hashCode() {
return studentFirstname.hashCode() + studentLastname.hashCode();
}
}
}
教师.java
@Entity
public class Teacher {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstname;
private String lastname;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(
name="STUDENT_TEACHER",
joinColumns=@JoinColumn(name="TEACHER_ID"),
inverseJoinColumns={
@JoinColumn(name="STUDENT_FIRSTNAME"),
@JoinColumn(name="STUDENT_LASTNAME")
}
)
private Set<Student> students = new HashSet<Student>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public Set<Student> getStudents() {
return students;
}
public void addStudents(Student student) {
students.add(student);
}
}
您只需要根据您的特定情况调整代码即可。我希望你能用这个答案解决你的问题。
编辑:
我让 Hibernate 创建表,并将hbm2ddl.auto
选项设置为update
. 它创建了一个STUDENT
表、一个TEACHER
表和一个STUDENT_TEACHER
连接表。我在这里添加CREATE TABLE
生成的语句(使用 MySQL):
学生表:
CREATE TABLE `student` (
`FIRST_NAME` varchar(255) NOT NULL,
`LAST_NAME` varchar(255) NOT NULL,
PRIMARY KEY (`FIRST_NAME`,`LAST_NAME`)
)
教师表:
CREATE TABLE `teacher` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`firstname` varchar(255) DEFAULT NULL,
`lastname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
)
STUDENT_TEACHER 表:
CREATE TABLE `student_teacher` (
`TEACHER_ID` bigint(20) NOT NULL,
`STUDENT_FIRSTNAME` varchar(255) NOT NULL,
`STUDENT_LASTNAME` varchar(255) NOT NULL,
PRIMARY KEY (`TEACHER_ID`,`STUDENT_FIRSTNAME`,`STUDENT_LASTNAME`),
KEY `FK13A0C19E102E6B8F` (`STUDENT_FIRSTNAME`,`STUDENT_LASTNAME`),
KEY `FK13A0C19EC177BFF2` (`TEACHER_ID`),
CONSTRAINT `FK13A0C19EC177BFF2` FOREIGN KEY (`TEACHER_ID`) REFERENCES `teacher` (`id`),
CONSTRAINT `FK13A0C19E102E6B8F` FOREIGN KEY (`STUDENT_FIRSTNAME`, `STUDENT_LASTNAME`) REFERENCES `student` (`FIRST_NAME`, `LAST_NAME`)
)