4.5.3.1.1. Declarative Creation

Typically, datasources are declared in the dsContext element of a screen descriptor. Depending on the relative position of declaration elements, sources of two varieties are created:

  • if an element is located directly in dsContext, a normal Datasource or CollectionDatasource, which contains an independently loaded entity or collection, is created;

  • if an element is located inside an element of another source, NestedDatasource is created and the external source becomes its parent.

Below is an example of declaring a data source:

<dsContext>
    <datasource id="carDs" class="com.haulmont.sample.entity.Car" view="carEdit">
        <collectionDatasource id="allocationsDs" property="driverAllocations"/>
        <collectionDatasource id="repairsDs" property="repairs"/>
    </datasource>

    <collectionDatasource id="colorsDs" class="com.haulmont.sample.entity.Color" view="_local">
        <query>
            select c from sample$Color c order by c.name
        </query>
    </collectionDatasource>
</dsContext>

In the example above, carDs contains one entity instance, Car, and nested allocationsDs and repairsDs contain collections of related entities from the Car.driverAllocations and Car.repairs attributes, respectively. The Car instance together with related entities is set into the data source from the outside. If this screen is an edit screen, it happens automatically when opening the screen. The colorsDs data source contains a collection of instances of the Color entity, which is loaded by the source itself using the specified JPQL query with the _local view.

Below is the XML scheme.

dsContext – root element.

dsContext elements:

  • datasource – defines a data source that contains a single entity instance.

    Attributes:

    • id – source identifier, must be unique for this DsContext.

    • class – Java class of an entity that will be contained in this source.

    • view – name of entity view. If the source itself loads instances, then this view will be used during loading. Otherwise, this view makes signals to external mechanisms on how to load an entity for this source.

    • allowCommit – if set to false, the isModified() method of this source always returns false and the commit() method does nothing. Thus, changes in entities that are contained in the source are ignored. By default, it is set to true, i.e., changes are traced and can be saved.

    • datasourceClass is a custom class of data source implementation, if necessary.

  • collectionDatasource – defines a data source that contains a collection of instances.

    collectionDatasource attributes:

    • refreshMode – a source update mode, default is ALWAYS. In the NEVER mode, when refresh() method is invoked, the source does not load data and only changes its state to Datasource.State.VALID, notifies listeners and sorts available instances. The NEVER mode is useful if you need to programmatically fill CollectionDatasource with preloaded or created entities. For example:

      @Override
      public void init(Map<String, Object> params) {
          Set<Customer> entities = (Set<Customer>) params.get("customers");
          for (Customer entity : entities) {
              customersDs.includeItem(entity);
          }
          customersDs.refresh();
      }

    • softDeletion – the false value disables the soft deletion mode when loading entities, i.e., deleted instances will also be loaded. Default value is true.

    collectionDatasource elements:

    • query – query to load entities

  • groupDatasource – completely similar to collectionDatasource, but creates data source implementation that is suitable to use in conjunction with the GroupTable component.

  • hierarchicalDatasource – similar to collectionDatasource, and creates data source implementation that is suitable to use in conjunction with the Tree and TreeTable components.

    hierarchyProperty is a specific attribute. It specifies an attribute name, upon which a hierarchy is built.

A source implementation class is selected implicitly based on the name of the XML element and, as mentioned above, the mutual arrangement of elements. However, if you need to apply a custom data source, you can explicitly specify its class in the datasourceClass attribute.