如何为连接表中的其他属性创建多对多 Hibernate 映射?

Posted

技术标签:

【中文标题】如何为连接表中的其他属性创建多对多 Hibernate 映射?【英文标题】:How Do I Create Many to Many Hibernate Mapping for Additional Property from the Join Table? 【发布时间】:2012-05-04 21:05:32 【问题描述】:

我需要一个多对多休眠映射,需要 3 个连接。我试图找到一个没有像LecturerCourse 这样的中间实体的解决方案。

我的数据库中的讲师和课程表之间存在多对多关系。一个课程可以由多个讲师讲授,而一个讲师可以讲多个课程。

我已经预先存储了课程。但是,我需要将课程分配给讲师。当我分配课程时,我还会存储该课程的容量。

我的数据库图:

我使用休眠和弹簧。当课程分配任何讲师时,我需要一个休眠映射。我需要向容量字段添加值。

我的讲师映射:

@Entity
@Table(name="LECTURER")
public class Lecturer 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="LECTURER_ID_SEQ")
    @SequenceGenerator(name="LECTURER_ID_SEQ", sequenceName="LECTURER_ID_SEQ")
    private Long Id;

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

    @Column(name="SURNAME")
    private String surname;


    @Column(name="EMAIL")
    private String email;

    @Column(name="USERNAME")
    private String username;

    @Column(name="PASSWORD")
    private String Password;

    @ManyToMany
    @JoinTable(
          name="LECTURER_COURSE",
          joinColumns=@JoinColumn(name="LECTURER_ID"),
          inverseJoinColumns=@JoinColumn(name="COURSE_ID")
      )
    private List<Course> courses;

    //getters - setters

我的课程映射:

@Entity
@Table(name="COURSE")
public class Course 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="COURSE_ID_SEQ")
    @SequenceGenerator(name="COURSE_ID_SEQ", sequenceName="COURSE_ID_SEQ")
    private Long id;

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

    @Column(name="CODE")
    private String code;

知道如何解决我的问题吗?

【问题讨论】:

你试过什么?如果您将课程添加到讲师,然后保存讲师,您能否在数据库中看到 LECTURER 和 LECTURER_COURSE 表是否已填充? 是的,它将填充数据库。我的问题是如何存储课程的容量值。一门课程可能对每位讲师具有多种能力。如何映射容量字段? 看看axtavt对这个问题的回答:***.com/questions/4751902/… 我希望这行得通。我会尝试。谢谢。 @erencan 你好,我也有同样的问题,你尝试过 John 提到的解决方案吗? 【参考方案1】:

你需要使用@EmbeddedId@Embeddable注解来解决这个问题:

讲师班:

@Entity
@Table(name="LECTURER")
public class Lecturer 

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.lecturer", cascade=CascadeType.ALL)
Set<LecturerCourse> lecturerCourses == new HashSet<LecturerCourse>();

//all others properties Setters and getters are less relevant.


课程类别:

@Entity
@Table(name="COURSE")
public class Course 

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.course", cascade=CascadeType.ALL)
Set<LecturerCourse> lecturerCourses == new HashSet<LecturerCourse>();

//all others properties Setters and getters are less relevant.


讲师课程类:

@Entity
@Table(name = "lecturer_course")
@AssociationOverrides(
        @AssociationOverride(name = "pk.lecturer", 
            joinColumns = @JoinColumn(name = "LECTURER_ID")),
        @AssociationOverride(name = "pk.course", 
            joinColumns = @JoinColumn(name = "COURSE_ID")) )
public class LecturerCourse 

    private LecturerCourseID pk = new LecturerCourseID();

    @Column(name = "CAPACITY", nullable = false, length = 10)
    private String capacity;

    @EmbeddedId
    public LecturerCourseID getPk() 
        return pk;
    


现在是主键:

@Embeddable
public class LecturerCourseID implements java.io.Serializable 

    private Lecturer lecturer;
    private Course course;

    @ManyToOne
    public Stock getLecturer() 
        return lecturer;
    

    public void setLecturer(Lecturer lecturer) 
        this.lecturer= lecturer;
    

    @ManyToOne
    public Course getCourse() 
        return course;
    

    public void setCourse(Course course) 
        this.course= course;
    


现在你的 Main 应该是这样的:

Lecturer lecturer1 = new Lecturer();
Course math = new Course();
LecturerCourse lecturer1math  = new LecturerCourse();
lecturer1math.setCapacity("capacity");
lecturer1math.setLecturer(lecturer1);
lecturer1math.setCourse(math);
lecturer1.getLecturerCourses().add(lecturer1math);

//saving object
session.save(lecturer1);

您需要确保标记为@Embeddable 的类应该实现Serializable 标记接口。

希望对你有帮助。

【讨论】:

非常感谢您的详细解答。我解决了与您的回复类似的问题。但是,我想知道是否有没有像 LecturerCourse 这样的中间实体的解决方案。我试过那些***.com/questions/4751902/…。但它不起作用。我阅读了文档docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/…。仍然无法解决问题。 不幸的是,我不熟悉另一种方法。在您的情况下,我正在使用上面的代码创建复合主键和额外的列。 我明白了。再次感谢。如果我能找到解决方案。我也会发给你的。 lecture1math 没有设置器,您也没有明确表示您像对待实体类一样忽略它们。 lecture1math 也没有讲师和课程的字段,所以我也不能假设您的代码是正确的。 @ds011591 你可以通过使用瞬态getter来获得它:`@Transient public Item getCourse() return getPk().getCourse(); `

以上是关于如何为连接表中的其他属性创建多对多 Hibernate 映射?的主要内容,如果未能解决你的问题,请参考以下文章

如何为多对多关系创建 initial_data Json 夹具?

反对 js:无法使用连接表额外属性更新多对多关系。说附加属性无效

多对多关系 - 如何更新数据透视表中的属性

从多对多连接表中检索行的 HQL 查询

多对多关联表PK作为其他表中的FK

如何为 CoreData 多对多关系编写 NSPredicate