При использовании Java Persistence API (JPA) часто необходимо создавать отношения между двумя объектами. Эти отношения определяются в модели данных (думаю, база данных) с помощью внешних ключей и в нашей объектной модели (думаю, Java), используя аннотации для обозначения ассоциаций. При определении отношений или ассоциаций в объектной модели общей задачей является определение стороны-владельца отношений. Идентификация сущности-владельца внутри отношения важна, потому что сторона-владелец чаще всего, если не всегда, должна указывать аннотацию @JoinColumn. Чтобы проиллюстрировать концепцию собственной стороны объекта, мы будем использовать модель данных для поддержки этого обсуждения.
Давайте проанализируем эту простую модель, которая изображает взаимосвязь между двумя таблицами POST и SERIES. В этом отношении таблица POST хранит запись в блоге, которая может быть частью серии сообщений, представленных в таблице SERIES. В модели данных внешний ключ SERIES_ID в таблице POST связывает POST с соответствующей SERIES. Этот внешний ключ указывает, какой сущности принадлежит отношение. Давайте добавим эти объекты в объектную модель и установим простую однонаправленную связь между ними. Во-первых, сущность серии:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@Entity @Table (name= "SERIES" ) public class Series { @Id @GeneratedValue (strategy=GenerationType.AUTO) @Column (name= "SERIES_ID" ) private Integer seriesId; @Column (name= "TITLE" ) private String title; //Accessors... } |
И объект Post:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
@Entity @Table (name= "POST" ) public class Post { @Id @GeneratedValue (strategy=GenerationType.AUTO) @Column (name= "POST_ID" ) Integer postId; @Column (name= "TITLE" ) String title; @Column (name= "POST_DATE" ) Date postDate; @ManyToOne @JoinColumn (name= "SERIES_ID" ) private Series series; //Accessors... } |
В объекте Post аннотация @JoinColumn указана над полем Series для обозначения внешнего ключа, который будет использоваться для идентификации соответствующей серии Post. Аннотация @JoinColumn была помещена в сущность Post, поскольку она является сущностью-владельцем в отношении. Сторона-владелец объекта была определена путем ссылки на оба объекта в модели данных и определения объекта, содержащего внешний ключ. Если взаимосвязь между сущностями Post и Series должна была быть двунаправленной, то есть сущности Post должны быть доступны из Series, обратная сторона взаимосвязи (Series) должна быть аннотирована @OneToMany с определенным элементом mappedBy. Элемент mappedBy должен указывать на поле на стороне-владельце отношения (Post), которое указывает @JoinColumn, используемый для связывания сущностей.
Отображение для установления двунаправленной связи выделено в следующем рефакторинге объекта Series:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@Entity @Table (name= "SERIES" ) public class Series { @Id @GeneratedValue (strategy=GenerationType.AUTO) @Column (name= "SERIES_ID" ) private Integer seriesId; @Column (name= "TITLE" ) private String title; @OneToMany (mappedBy= "series" ) private List posts = new ArrayList(); //Accessors... } |
Таким образом, при определении сущности-владельца в отношении, определенном в единице постоянства JPA, важно обратиться к модели данных, чтобы найти, какие сущности соответствующей таблицы в модели данных содержат внешний ключ.