Hibernate多对多映射

时间:2013-09-04 10:49:48

标签: java entity-framework hibernate

我有一个现有的数据库建模方式如下:

学生 - SchoolId(PK)StudentId(PK)StudentName

教师 - SchoolId(PK)TeacherId(PK)TeacherName

Student_Teacher - SchoolId(PK)StudentId(PK)TeacherId(PK)

外部密钥引用存在于Student_Teacher到各个实体。

现在我正在为这个现有数据库创建hibernate实体。我遇到了从学生到教师创建多对多映射的奇怪问题。

@Entity
@Table(name = "Student")
public class Student {
    @EmbeddableId
    private StudentPK itemId;

    @Column(name="StudentName")
    private String studentName;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="Student_Teacher", joinColumns={@JoinColumn(name="SchoolId", referencedColumnName="SchoolId"),@JoinColumn(name="StudentId", referencedColumnName="StudentId")}, inverseJoinColumns={@JoinColumn(name="SchoolId", referencedColumnName="SchoolId"),@JoinColumn(name="TeacherId", referencedColumnName="TeacherId")})
    private List<Teacher> attachments=new ArrayList<Teacher>();
}

上面的代码补充了一些重复的SchoolId引用。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我发现你的实体映射存在问题,应该如下

学校 - school_id(PK)school_name

学生 - student_id(PK)student_namefk_school_id(FK)

老师 - teacher_id(PK)teacher_namefk_school_id(FK)

* student_teacher * - student_teacher_id(PK)fk_student_id(FK)fk_teacher_id(FK)

和Entity clasess如下

学校实体

@Entity
@Table(name = "school")
public class School {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column (name = "school_id")
   private int Id;

    @Column(name="school_name")
    private String schoolName;  

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "school")
   private Set<Student> students = new HashSet<Student>  

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "school")
   private Set<Teacher> teachers = new HashSet<Teacher> 
}

学生实体

@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column (name = "student_id")
    private int Id;

    @Column(name="student_name")
    private String studentName;

   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "school_id", nullable = false)
   private School school;       

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "student_teacher", joinColumns = {@JoinColumn(name = "fk_student_id") }, inverseJoinColumns = { @JoinColumn(name = "fk_teacher_id") })
    private List<Teacher> teachers = new ArrayList<Teacher>();

}

教师实体

@Entity
@Table(name = "teacher")
public class Teacher {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column (name = "teacher_id")
    private int Id;

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

   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "school_id", nullable = false)
   private School school;   

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "student_teacher", joinColumns = {@JoinColumn(name = "fk_teacher_id") }, inverseJoinColumns = { @JoinColumn(name = "fk_student_id") })
    private List<Student> students =new ArrayList<Student>();
}
希望这能解决这个问题。

因为您已在 Student_Teacher 表中声明'SchoolId' PK ,所以它不允许您添加 Student_Teacher 表的 SchoolId 字段的重复条目,情况并非如此。因此上述关系将给出重复的SchoolId参考。当你打算将同一所学校的两名不同学生加入 Student_Teacher 表时..

答案 1 :(得分:0)

您是否将每个实体的各种PK定义为复合键,因为我注意到每个实体使用多个PK。是否有任何约束为什么你不能使用每个实体的唯一PK并只使用关系表来绑定2个实体?