JPA "@JoinTable" аннотация

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

Ответ 1

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 называется "Join Table". Чтобы реализовать это второе решение в 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

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

Ответ 2

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

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

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

Ответ 3

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

Если task таблица имеет 5 nullable иностранных ключевых полей? Думаю, нет...

Ответ 4

Он позволяет обрабатывать отношения "многие-многие". Пример:

Table 1: post

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

Table 2: user

user has the following columns:

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

Таблица соединений позволяет создавать сопоставление, используя:

@JoinTable(
  name="USER_POST",
  [email protected](name="USER_ID", referencedColumnName="ID"),
  [email protected](name="POST_ID", referencedColumnName="ID"))

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

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