«1. Введение

Отношения JPA могут быть как однонаправленными, так и двунаправленными. Это просто означает, что мы можем смоделировать их как атрибут только одной из связанных сущностей или обеих.

Определение направления связи между сущностями не влияет на отображение базы данных. Он только определяет направления, в которых мы используем эти отношения в нашей модели предметной области.

Для двунаправленных отношений мы обычно определяем:

    сторона-владелец, обратная или сторона, на которую ссылается

Аннотация @JoinColumn помогает нам указать столбец, который мы будем использовать для присоединения к ассоциации сущностей или набору элементов. С другой стороны, атрибут mappedBy используется для определения ссылающейся стороны (не владеющей стороной) отношения.

В этом кратком руководстве мы рассмотрим разницу между @JoinColumn и mappedBy в JPA. Мы также покажем, как использовать их в ассоциации «один ко многим».

2. Первоначальная настройка

Чтобы следовать этому руководству, предположим, что у нас есть две сущности: Сотрудник и Электронная почта.

Понятно, что у сотрудника может быть несколько адресов электронной почты. Однако данный адрес электронной почты может принадлежать только одному сотруднику.

Это означает, что они имеют общую ассоциацию «один ко многим»:

Также в нашей модели СУБД у нас будет внешний ключ employee_id в нашей сущности электронной почты, ссылающийся на атрибут id сотрудника.

3. Аннотация @JoinColumn

В отношениях «один ко многим»/«многие к одному» сторона-владелец обычно определяется на стороне «многие» отношения. Обычно это сторона, которая владеет внешним ключом.

Аннотация @JoinColumn определяет фактическое физическое сопоставление на стороне-владельце:

@Entity
public class Email {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "employee_id")
    private Employee employee;

    // ...

}

Это просто означает, что наш объект электронной почты будет иметь столбец внешнего ключа с именем employee_id, ссылающийся на идентификатор основного атрибута нашего объекта Employee.

4. Атрибут mappedBy

После того, как мы определили владеющую сторону отношения, Hibernate уже имеет всю информацию, необходимую для сопоставления этого отношения в нашей базе данных. Чтобы сделать эту ассоциацию двунаправленной, все, что нам нужно сделать, это определить сторону ссылки. Обратная или ссылающаяся сторона просто сопоставляется со стороной-владельцем.

Для этого мы можем легко использовать атрибут mappedBy аннотации @OneToMany. Итак, давайте определим нашу сущность Employee:

@Entity
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "employee")
    private List<Email> emails;
    
    // ...
}

Здесь значением mappedBy является имя атрибута сопоставления ассоциации на стороне-владельце. Таким образом, мы установили двунаправленную ассоциацию между нашими объектами Employee и Email.

5. Заключение

В этом уроке мы рассмотрели разницу между @JoinColumn и mappedBy и то, как их использовать в двунаправленных отношениях «один ко многим».

Аннотация @JoinColumn определяет фактическое физическое сопоставление на стороне владельца. С другой стороны, сторона ссылки определяется с помощью атрибута mappedBy аннотации @OneToMany.

Как обычно, исходный код доступен на Github.