JPA连接具有相同名称的外键

时间:2017-08-28 09:45:18

标签: hibernate jpa orm

我想我有:

  1. 编辑(id,business_name,增值税)
  2. 作者(ID,姓名,电子邮件)
  3. 图书(ID,标题,说明,fk_author,fk_editor)。
  4. 假设 fk_editor 是表格编辑器的id字段的外键, fk_author 是表格作者的id字段的外键。

    假设关系书籍:作者 n:1 书籍:编辑 n:1

    问题是:如何加入三个表通过书籍表? 这意味着,我必须在Book类中添加什么代码才能让Hibernate理解为与作者和编辑者建立关系?考虑一下我在作者和编辑器中有相同的id字段名称。 这是我需要纠正的示例代码:

    作者

    package com.bytecode.jpaexample.SpringBootMySqlJpaRestExample;
    
    import javax.persistence.*;
    import java.io.Serializable;
    
    @Entity
    @Table(name = "authors")
    public class Author implements Serializable{
    
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       @Column(name = "id")
       @OneToMany(fetch = FetchType.LAZY)
       private int id;
    
       @Column(name = "name")
       private String name;
    
       @Column(name = "surname")
       private String surname;
    
       @Column(name = "email")
       private String email;
    
       /* constructors and getters and setters omitted intentionally */
    
    }
    

    编辑

    package com.bytecode.jpaexample.SpringBootMySqlJpaRestExample;
    
    import javax.persistence.*;
    import java.io.Serializable;
    
    @Entity
    @Table(name = "editors")
    public class Editor implements Serializable{
    
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       @Column(name = "id")
       @OneToMany(fetch = FetchType.LAZY)
       private int id;
    
       @Column(name = "business_name")
       private String businessName;
    
       @Column(name = "vat")
       private String vat;
    
       /* constructors and getters and setters omitted intentionally */
    
    }
    

    图书

    package com.bytecode.jpaexample.SpringBootMySqlJpaRestExample;
    
    import javax.persistence.*;
    import java.io.Serializable;
    
    @Entity
    @Table(name="books")
    public class Book implements Serializable{
    
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       @Column(name = "id")
       private int id;
    
       @Column(name = "title")
       private String title;
    
       @Column(name = "description")
       private String description;
    
       @ManyToOne(fetch = FetchType.LAZY)      
       @JoinColumn(name = "id") //authors.id                
       @Column(name = "fk_author")
       private int fk_editor;
    
       @ManyToOne(fetch = FetchType.LAZY)      
       @JoinColumn(name = "id") //editors.id                
       @Column(name = "fk_editor")
       private int fk_editor;
    
       /* constructors and getters and setters omitted intentionally */
    }
    

1 个答案:

答案 0 :(得分:1)

有几件事:

AuthorEditor类不应将id字段注明为@OneToMany

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

相反,我猜你想在每个班级中想要另一个领域:

@Entity
@Table(name = "authors")
public class Author implements Serializable {
    ...
    @OneToMany(mappedBy = "author", fetch = FetchType.LAZY)
    private List<Book> books;
    ...
}

@Entity
@Table(name = "editors")
public class Editor implements Serializable {
    ...
    @OneToMany(mappedBy = "editor", fetch = FetchType.LAZY)
    private List <Book> books;
    ...
}

然后,您需要以多种方式更改班级Book

  • 更恰当地重命名字段(例如fk_author变为author);这些必须与相应类中的mappedBy设置匹配,如上所述)
  • 将字段类型更改为相应的类(例如Author),外键类型(例如int
  • 更改@JoinColumn注释以指定books表中的相应列(目标表)并添加referencedColumnName设置(尽管这些是在这种情况下是可选的;因为它们将默认为目标实体上的单个主键字段)
  • 删除@Column注释

看看这是否有意义:

@Entity
@Table(name="books")
public class Book implements Serializable {
    ...
    @ManyToOne(fetch = FetchType.LAZY)      
    @JoinColumn(name = "fk_author", referencedColumnName="id")
    private Author author;

    @ManyToOne(fetch = FetchType.LAZY)      
    @JoinColumn(name = "fk_editor", referencedColumnName="id")
    private Editor editor;
    ...
}