我与Mentor to Students的实体之间的关系低于1米。导师有复合主键,我在学生中用作外键
@Entity
public class Mentor implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private MentorPK id;
private String email;
@OneToMany(mappedBy="mentor")
private Set<Student> students;
public MentorPK getId() {
return id;
}
//getters and setters
}
@Embeddable
public class MentorPK implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String add;
//getters and setters
//override equals and hashcode
}
@Entity
public class Student implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
@ManyToOne
@MapsId("id")
@JoinColumns({
@JoinColumn(name="name_fk", referencedColumnName="name"),
@JoinColumn(name="address_fk", referencedColumnName="address")
})
private Mentor mentor;
//Getters and setters
}
然后我坚持上面的内容如下,但只有导师在学生桌空的地方持续存在。
如何与学生一起坚持导师?
Set<Student> students = new HashSet<Student>();
Student s1 = new Student();
s1.setName("Student 1");
Student s2 = new Student();
s2.setName("Student 2");
students.add(s1);
students.add(s2);
MentorPK mpk = new MentorPK();
mpk.setAddress("C");
mpk.setName("D");
Mentor m = new Mentor();
m.setId(mpk);
m.setEmail("emaill");
m.setStudents(students);
studentManager.saveMentor(m);
答案 0 :(得分:2)
尝试将学生字段的注释更改为
@OneToMany(mappedBy="mentor", cascade = CascadeType.PERSIST)
答案 1 :(得分:2)
当您使用复合键时,映射为Embeddable,您需要使用@EmbeddedId:
@Entity
public class Mentor {
@EmbeddedId
private MentorPK id;
private String email;
@OneToMany(mappedBy="mentor")
private Set<Student> students;
public MentorPK getId() {
return id;
}
//getters and setters
}
并且学生变成:
@Entity
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
@ManyToOne
@JoinColumns({
@JoinColumn(name="name_fk", referencedColumnName="name"),
@JoinColumn(name="address_fk", referencedColumnName="address")
})
private Mentor mentor;
//Getters and setters
}
当@MapsId
和@Id
共享相同的数据库列时使用@ManyToOne
,这不是您的情况,因为您有一个数字标识符和一个复合外键
答案 2 :(得分:2)
您可能需要在每位学生中创建从学生到导师的参考。
因此,在您的代码中,创建m
后,您需要:
s1.setMentor(m);
s2.setMentor(m);
否则,Hibernate可能不知道用{。{1}}和name_fk
填充列的内容。
答案 3 :(得分:1)
如何改变:
ng-style
为:
@OneToMany(mappedBy="mentor")
private Set<Student> students;
或
@OneToMany(mappedBy="mentor")
private Set<Student> students = new HashSet();
也尽量不要跳过
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="student_id")
@org.hibernate.annotations.IndexColumn(name="idx")
private Set<Student> students = new HashSet();
部分
答案 4 :(得分:1)
据我了解您的要求,您希望Mentor成为该关系的所有者。您没有使用行@OneToMany(mappedBy="mentor")
获取此信息。这实际上将学生作为关系的所有者。
我测试了这个域模型,并对注释做了一些修改,以使测试代码按预期工作。
<强>学生强>
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private int id;
private String name;
@ManyToOne
@JoinColumns({
@JoinColumn(name="name_fk", referencedColumnName="name", insertable = false, updatable = false),
@JoinColumn(name="address_fk", referencedColumnName="address", insertable = false, updatable = false )
})
private Mentor mentor;
//setters and getters
}
<强>明导强>
public class Mentor implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private MentorPK id;
private String email;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumns({
@JoinColumn(name="name_fk", referencedColumnName="name"),
@JoinColumn(name="address_fk", referencedColumnName="address")
})
private Set<Student> students;
//setters and getters
}
它甚至无需执行:s1.setMentor(m);s2.setMentor(m);
。我没想到它,但似乎hibernate正在处理这个问题。
相关文章为here。
注意:在更改注释后删除数据库表,以便允许hibernate重新创建表。