Как аннотировать Entity для создания таблицы отношений?
Я создаю приложение с DataJpa.
У меня есть сущность Dish:
CREATE TABLE dishes
(
id INTEGER GENERATED BY DEFAULT AS SEQUENCE GLOBAL_SEQ PRIMARY KEY,
name VARCHAR(255) NOT NULL,
);
Имеется также сущность Menu:
CREATE TABLE menus
(
id INTEGER GENERATED BY DEFAULT AS SEQUENCE GLOBAL_SEQ PRIMARY KEY,
date DATE NOT NULL,
);
И ещё я сделал таблицу их отношений:
CREATE TABLE menu_dishes
(
dish_id INTEGER NOT NULL,
menu_id INTEGER NOT NULL,
CONSTRAINT menu_dishes_menu_dish_idx UNIQUE (menu_id, dish_id),
FOREIGN KEY (dish_id) REFERENCES dishes (id) ON DELETE CASCADE,
FOREIGN KEY (menu_id) REFERENCES menus (id) ON DELETE CASCADE
);
Почему бы просто не сделать в Dish FK на Menu, зачем делать эту третью таблицу? Всё потому что я хочу, чтобы для каждого нового Menu не надо было создавать новые Dish, когда можно было бы взять старые и заставить их ссылаться на Menu, т.е. вместо создания новых Dish, я хочу создавать новые отношения.
У меня возникла проблема с маппингом. Menu я сделал вот так:
@Entity
@Table(name = "menus")
public class Menu {
@CollectionTable(name = "menu_dishes", joinColumns = "menu_id")
@ElementCollection(fetch = FetchType.EAGER)
private List<Dish> dishes;
Но что-то мне подсказывает, что этого недостаточно. Что мне ещё необходимо сделать, чтобы реализовать такую таблицу отношений? Какие изменения мне нужно сделать в классах Dish и Menu?
Ответы (1 шт):
Для таблицы отношений используется аннотация @ManyToMany
С её помощью для каждого нового Menu не надо будет создавать новую сущность Dish, когда можно использовать старую. Для связывания сущностей ManyToMany необходимо прописать следующие аннотации в одной сущности:
@Entity
@Table(name = "menus")
public class Menu extends AbstractBaseEntity {
@ManyToMany
@JoinTable(
name = "menu_dishes",
joinColumns = @JoinColumn(name = "menu_id"),
inverseJoinColumns = @JoinColumn(name = "dish_id")
)
private List<Dish> dishes;
и в другой:
@Entity
@Table(name = "dishes")
public class Dish extends AbstractNamedEntity {
@ManyToMany(mappedBy = "dishes")
private List<Menu> menu;
Причём не имеет значения, в какой из них будут прописаны конкретные аннотации. В joinColumn указывается колонка, на которую будет маппится целевая сущность. В inverseJoinColumns в свою очередь указывается колонка, на которую будет маппится связанная сущность.