Как аннотировать 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 шт):

Автор решения: Zhenyria

Для таблицы отношений используется аннотация @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 в свою очередь указывается колонка, на которую будет маппится связанная сущность.

→ Ссылка