JPA "@JoinTable" аннотация - PullRequest
125 голосов
/ 30 марта 2011

В каком случае вы используете JPA @JoinTable аннотацию?

Ответы [ 4 ]

308 голосов
/ 30 марта 2011

РЕДАКТИРОВАТЬ 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. Например, чтобы реализовать однонаправленную связь «один ко многим», мы можем определить наши сущности так:

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

}

Это создаст следующую структуру базы данных:

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

Наконец, если вы хотите создать схему для связи «многие ко многим», единственным доступным решением будет использование таблицы соединений.

13 голосов
/ 02 января 2014

Также лучше использовать @JoinTable, когда сущность может быть ребенком в нескольких отношениях родитель / ребенок с разными типами родителей. Чтобы следовать примеру Бехранга, представьте, что задание может быть дочерним для проекта, человека, отдела, обучения и процесса.

Должна ли таблица task иметь 5 nullable полей внешнего ключа? Я думаю нет ...

13 голосов
/ 30 марта 2011

Это единственное решение для сопоставления ассоциации ManyToMany: вам нужна таблица соединения между двумя таблицами сущностей для сопоставления ассоциации.

Он также используется для ассоциаций OneToMany (обычно однонаправленных), когда вы не хотите добавлять внешний ключ в таблицу многих сторон и таким образом сохранять его независимым от одной стороны.

Поиск @JoinTable в документации по гибернации для объяснений и примеров.

4 голосов
/ 02 июня 2017

Это позволяет вам обрабатывать отношения «многие ко многим».Пример:

Table 1: post

post has following columns
____________________
|  ID     |  DATE   |
|_________|_________|
|         |         |
|_________|_________|

Table 2: user

user has the following columns:

____________________
|     ID  |NAME     |
|_________|_________|
|         |         |
|_________|_________|

Присоединить таблицу позволяет создать сопоставление с помощью:

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

создаст таблицу:

____________________
|  USER_ID| POST_ID |
|_________|_________|
|         |         |
|_________|_________|
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...