5.8.3.2. Deep Composition

Composition can be deeper, with several nested levels. Let’s extend the example above by adding a MeetingPoint entity describing a meeting point at an airport terminal:

composition recipe 2

The Terminal entity contains the meetingPoints attribute – a collection of the MeetingPoint instances. In order for all three entities to become a single composition and be edited together, you should do the following in addition to the steps described above:

  1. Mark the meetingPoints attribute of the Terminal class as @Composition and @OnDelete similarly to the terminals attribute of the Airport class.

  2. Create a new view for the Terminal:

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

    Use it in the Airport view instead of _local:

    <view entity="sample$Airport" name="airport-edit" extends="_local">
        <property name="terminals" view="terminal-edit"/>
    </view>
  3. Define datasources for an instance of the Airport and nested entities for the entire composition depth in the Airport edit screen XML descriptor:

    <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>

    Here, the meetingPointsDs datasource is not associated with any visual components, however it is needed for correct operation of joint editing of the composition.

  4. Define the nested data source and a corresponding table for the meetingPoints collection in the terminal edit screen XML descriptor.

As a result, the updated instances of the MeetingPoint, as well as the Terminal instances, will be saved to the database only with the Airport instance in the same transaction.