JPA“@JoinTable”注释

在这种情况下,你使用JPA @JoinTable注解吗?

编辑2017-04-29 :正如一些评论者所指出的, JoinTable示例不需要mappedBy注释属性。 实际上,最近的Hibernate版本通过打印下面的错误拒绝启动:

 org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn 

假设您有一个名为Project的实体,另一个名为Task实体,每个项目都可以有许多任务。

您可以通过两种方式为此schemedevise数据库模式。

第一个解决scheme是创build一个名为Project的表和另一个名为Task表,并将外键列添加到名为project_id的任务表中:

 Project Task ------- ---- id id name name project_id 

这样就可以确定任务表中每一行的项目。 如果你使用这种方法,在你的实体类中你将不需要一个连接表:

 @Entity public class Project { @OneToMany(mappedBy = "project") private Collection<Task> tasks; } @Entity public class Task { @ManyToOne private Project project; } 

另一种解决scheme是使用第三个表,例如Project_Tasks ,并在该表中存储项目和任务之间的关系:

 Project Task Project_Tasks ------- ---- ------------- id id project_id name name task_id 

Project_Tasks表被称为“join表”。 要在JPA中实现这个第二个解决scheme,你需要使用@JoinTable注解。 例如,为了实现单向的一对多关联,我们可以像这样定义我们的实体:

Project实体:

 @Entity public class Project { @Id @GeneratedValue private Long pid; private String name; @JoinTable @OneToMany private List<Task> tasks; public Long getPid() { return pid; } public void setPid(Long pid) { this.pid = pid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Task> getTasks() { return tasks; } public void setTasks(List<Task> tasks) { this.tasks = tasks; } } 

Task实体:

 @Entity public class Task { @Id @GeneratedValue private Long tid; private String name; public Long getTid() { return tid; } public void setTid(Long tid) { this.tid = tid; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 

这将创build以下数据库结构:

ER图1

@JoinTable注解还允许您自定义连接表的各个方面。 例如,如果我们注释了这样的tasks属性:

 @JoinTable( name = "MY_JT", joinColumns = @JoinColumn( name = "PROJ_ID", referencedColumnName = "PID" ), inverseJoinColumns = @JoinColumn( name = "TASK_ID", referencedColumnName = "TID" ) ) @OneToMany private List<Task> tasks; 

结果数据库将变成:

ER图2

最后,如果要为多对多关联创build模式,则使用连接表是唯一可用的解决scheme。

这是映射ManyToMany关联的唯一解决scheme:您需要在实体表之间build立一个连接表来映射关联。

它也被用于OneToMany(通常是单向的)关联,当你不想在多方的表中添加一个外键,从而保持它与一方无关。

在hibernate文档中search@JoinTable以获取解释和示例。

当一个实体可能是不同父types的父/子关系的孩子时,使用@JoinTable也更为清晰。 跟随Behrang的例子,设想一个Task可以是Project,Person,Department,Study和Process的孩子。

task表是否应该有5个nullable外键字段? 我想不是…

它可以让你处理多对多的关系。 例:

 Table 1: post post has following columns ____________________ | ID | DATE | |_________|_________| | | | |_________|_________| Table 2: user user has the following columns: ____________________ | ID |NAME | |_________|_________| | | | |_________|_________| 

连接表让你创build一个映射使用:

 @JoinTable( name="USER_POST", joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="ID"), inverseJoinColumns=@JoinColumn(name="POST_ID", referencedColumnName="ID")) 

将创build一个表格:

 ____________________ | USER_ID| POST_ID | |_________|_________| | | | |_________|_________|