使用spring,hibernate,JPA Annotations在连接表中添加更多列

时间:2013-06-29 17:47:34

标签: hibernate spring-mvc jpa

我们可以在连接表注释中添加更多列吗?通常我会看到人们最后添加两列,如下例所示。

@JoinTable(name="mapping_table",
               joinColumns={@JoinColumn(name="request_id")},
               inverseJoinColumns={@JoinColumn(name="requester_id")})

有没有什么方法可以添加另一个列,比如另一个'@JoinColumn'?我的意思如下所示。

@JoinTable(name="mapping_table",
                   joinColumns={@JoinColumn(name="request_id")},
                   inverseJoinColumns={@JoinColumn(name="requester_id")
                                       @JoinColumn(name="requester_id")})

或者有另一个“inverseJoinColumn”。我试过找到解决方案无法弥补。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

使用@javax.persistence.JoinColumns(注意末尾的'')注释来定义复合外键的映射。您应该具有以下内容:

@JoinTable(name="mapping_table",
               joinColumns={@JoinColumn(name="request_id")},
               inverseJoinColumns={@JoinColumns({
                   @JoinColumn(name="requester_id"),
                   @JoinColumn(name="requester_id")})
               }
)

我认为它应该有效。

对不起第一个答案:我认为@JoinColumns注释不能在@JoinTable注释中使用。所以我决定多研究一下。

我创建了2个表:

  1. 具有由名字和姓氏组成的嵌入式ID的Student实体类。
  2. Teacher实体类,其中包含自动长ID和Set<Student>属性。
  3. 我使用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个实体的代码:

    Student.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();
            }
        }
    }
    

    Teacher.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`)
    )