5.8.3.2. Глубокая композиция

Композиция может быть более глубокой, то есть состоять из нескольких уровней вложенности. Усложним приведенный выше пример, добавив сущность MeetingPoint, описывающую место встречи у терминала аэропорта:

Теперь сущность Terminal содержит атрибут meetingPoints - коллекцию экземпляров MeetingPoint. Для того, чтобы все три сущности представляли собой единую композицию и редактировались совместно, нужно в дополнение к описанному в предыдущем разделе выполнить следующее:

  1. Атрибуту meetingPoints класса Terminal добавить аннотации @Composition и @OnDelete аналогично атрибуту terminals класса Airport.

  2. Создать новое представление для Terminal:

    <view entity="sample$Terminal" name="terminal-edit" extends="_local">
        <property name="meetingPoints" view="_local"/>
    </view>

    И использовать его в представлении Airport вместо _local:

    <view entity="sample$Airport" name="airport-edit" extends="_local">
        <property name="terminals" view="terminal-edit"/>
    </view>
  3. В XML-дескрипторе экрана редактирования аэропорта определить источники данных для экземпляра Airport и вложенных сущностей на всю глубину композиции:

    <dsContext>
        <datasource id="airportDs"
                    class="com.haulmont.sample.entity.Airport"
                    view="airport-edit">
            <collectionDatasource id="terminalsDs" property="terminals">
                <collectionDatasource id="meetingPointsDs" property="meetingPoints"/>
            </collectionDatasource>  
        </datasource>
    </dsContext>

    Здесь источник данных meetingPointsDs не связан ни с какими визуальными компонентами, однако он необходим для корректной работы совместного редактирования композиции.

  4. В XML-дескрипторе экрана редактирования терминала в свою очередь определить для коллекции meetingPoints вложенный источник данных и соответствующую таблицу.

В результате измененные эземпляры MeetingPoint, так же как и экземпляры Terminal, будут сохраняться в базу данных только вместе с экземпляром Airport в одной транзакции.