4.2.3.1. Прямая ассоциация Many-to-Many

Рассмотрим реализацию ассоциации many-to-many на примере сущностей Airport и Airline. Один аэропорт может принимать множество авиакомпаний, и одна авиакомпания-перевозчик, в свою очередь, может осуществлять рейсы во множество аэропортов.

association recipe 1
  • Airport.java - сущность Airport содержит many-to-many список авиакомпаний.

    В редакторе сущностей Studio установите следующие свойства для атрибута airlines: Attribute type - ASSOCIATION, Cardinality - MANY_TO_MANY.

    Сущность Airport будет отмечена ведущей стороной ассоциации, и Studio предложит создать соответствующий атрибут airports в сущности Airline на противоположной стороне отношений.

    @JoinTable(name = "SAMPLE_AIRLINE_AIRPORT_LINK",
        joinColumns = @JoinColumn(name = "AIRPORT_ID"),
        inverseJoinColumns = @JoinColumn(name = "AIRLINE_ID"))
    @ManyToMany
    protected List<Airline> airlines;
  • Airline.java - сущность Airline теперь содержит many-to-many список аэропортов: Attribute type - ASSOCIATION, Cardinality - MANY_TO_MANY.

    @JoinTable(name = "SAMPLE_AIRLINE_AIRPORT_LINK",
        joinColumns = @JoinColumn(name = "AIRLINE_ID"),
        inverseJoinColumns = @JoinColumn(name = "AIRPORT_ID"))
    @ManyToMany
    protected List<Airport> airports;

    Сущность Airline также будет отмечена как ведущая сторона отношений, что позволяет редактировать коллекции с обеих сторон.

  • views.xml - представление airport-airlines экрана редактирования аэропорта содержит ссылки на авиакомпании с представлением _minimal. Представление airline-airports, в свою очередь, также содержит ссылки на аэропорты.

  • airport-edit.xml - XML-дескриптор экрана редактирования аэропорта определяет источник данных для экземпляра аэропорта и вложенный источник для его авиакомпаний. Кроме того, экран содержит таблицу, отображающую авиакомпании, и действия add и remove для неё.

  • airline-edit.xml - XML-дескриптор экрана редактирования авиакомпании определяет источник данных для экземпляра авиакомпании и вложенный источник данных для её аэропортов. Кроме того, экран содержит таблицу, отображающую аэропорты, и действия add и remove.

    Таким образом, экраны редактирования сущностей Airport и Airline полностью симметричны.

В результате редактирование экземпляра авиакомпании работает следующим образом:

В экране редактирования авиакомпании отображается список аэропортов.

Пользователь может нажать Add и в открывшемся экране выбора сущности Airport либо выбрать аэропорт, который нужно добавить, либо открыть экран его редактирования. При нажатии OK в экране редактирования аэропорта изменённый экземпляр аэропорта сохраняется как в базу данных, так и в источник данных airportsDs экрана редактирования авиакомпании, так как сущность Airport является полностью независимой.

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

Пользователь нажимает OK в экране редактирования авиакомпании, и изменённый экземпляр Airline вместе со всеми ссылками на экземпляры Airport отправляется на middleware в метод DataManager.commit(), чтобы быть сохранённым в базе данных.

На другой стороне отношений в экране редактирования сущности Aiport работает ровно тот же принцип.