java - 在哪种情况下您使用 JPA @JoinTable 注释?

标签 java hibernate jpa many-to-many hibernate-mapping

在什么情况下你使用JPA @JoinTable注解?

最佳答案

EDIT 2017-04-29:正如一些评论者所指出的,JoinTable 示例不需要 mappedBy 注释属性.事实上,最新版本的 Hibernate 通过打印以下错误来拒绝启动:

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

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

您可以通过两种方式为此场景设计数据库架构。

第一个解决方案是创建一个名为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;

}

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

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

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

项目实体:

@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;
    }
}

任务实体:

@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;
    }

}

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

ER Diagram 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 Diagram 2

最后,如果您想为多对多关联创建架构,使用连接表是唯一可用的解决方案。

关于java - 在哪种情况下您使用 JPA @JoinTable 注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5478328/

相关文章:

java - 如何在hibernate环境中查询RevisionEntity

java - 使用 JPA LocalContainerEntityManagerFactoryBean 进行 Hibernate 配置

java - 我是否需要关闭 PipedInputStream 和 PipedOutputStream

Java - 用 printf 动态向左填充

hibernate - 标准与预测相结合

java - 如何通过引用键相关的其他表字段查找(使用JPA)?

java - 抛出应用程序异常会导致TransactionalException

java - Eclipse - 无需鼠标即可通过超链接转到类/界面

java - Maven 和多个客户定制

java - 查询两个日期之间的所有 Hibernate Envers 修订