5.5.3. Datasources
Datasources provide data to data-aware components.
Visual components themselves do not access Middleware: they get entity instances from linked datasources. Furthermore, one datasource can work with multiple visual components if they need the same instance or set of instances.
-
When a user changes a value in the component, the new value is set for the entity attribute in the datasource.
-
When the entity attribute is modified in the code, the new value is set and displayed in the visual component.
-
User input can be monitored both by datasource listeners and value listeners on the component – they are notified sequentially.
-
To read or write the value of an attribute in the application code, it is recommended to use the datasource, rather than the component. Below is an example of reading the attribute:
@Inject private FieldGroup fieldGroup; @Inject private Datasource<Order> orderDs; @Named("fieldGroup.customer") private PickerField customerField; public void init(Map<String, Object> params){ Customer customer; // Get customer from component: not for common use Component component = fieldGroup.getFieldNN("customer").getComponentNN(); customer = ((HasValue)component).getValue(); // Get customer from component: recommended customer = customerField.getValue(); // Get customer from datasource customer = orderDs.getItem().getCustomer(); }
As you can see, working with entity attribute values through a component is not very straightforward. In the first example, it requires type casting and specifying FieldGroup field
id
as a string. The second example is more safe and direct, but requires you to know exactly the type of the field to be injected. At the same time, if the instance is obtained from the datasource via thegetItem()
method, the values of attributes can be read and modified directly.
Datasources also track changes in entities contained therein and can send modified instances back to the middleware for storing in the database.
Warning
|
Typically, a visual component is bound to an attribute that directly belongs to the entity in the datasource. In the example above, the component is bound to the A component can also be associated with an attribute of a related entity, for example, |
The basic interfaces of datasources are described below.
-
Datasource is a simple datasource designed to work with one entity instance. The instance is set by the
setItem()
method and is accessed viagetItem()
.DatasourceImpl
class is the standard implementation of such datasource, which is used, for instance, as a main datasource on entity edit screens. -
CollectionDatasource is a datasource designed to work with a collection of entity instances. The collection is loaded with the invocation of the
refresh()
method, instance keys are accessible through thegetItemIds()
method. ThesetItem()
method sets the "current" instance of the collection andgetItem()
returns it (for example, the one that corresponds to the currently selected table row).The way of loading collections is determined by implementation. The most typical one is loading from Middleware via DataManager; in this case,
setQuery()
,setQueryFilter()
are used to form a JPQL query.CollectionDatasourceImpl
class is the standard implementation of such datasources, which is used on screens with entity lists.-
GroupDatasource is a subtype of
CollectionDatasource
, designed to work with the GroupTable component.Standard implementation is the
GroupDatasourceImpl
class. -
HierarchicalDatasource is a subtype of
CollectionDatasource
, designed to work with the Tree and TreeTable components.Standard implementation is the
HierarchicalDatasourceImpl
class.
-
-
NestedDatasource is a datasource designed to work with instances that are loaded in an attribute of another entity. In this case, a datasource that contains a parent entity is accessible via
getMaster()
, and meta property that corresponds to the parent attribute containing instances of this datasource is accessible viagetProperty()
.For example an
Order
instance which contains a reference to theCustomer
instance is set in thedsOrder
datasource. Then, to link theCustomer
instance with visual components, it is enough to createNestedDatasource
withdsOrder
as parent and meta property to point to theOrder.customer
attribute.-
PropertyDatasource is a subtype of
NestedDatasource
, designed to work with one instance or collection of related entities that are not embedded.Standard implementations: for working with one instance –
PropertyDatasourceImpl
, with a collection –CollectionPropertyDatasourceImpl
,GroupPropertyDatasourceImpl
,HierarchicalPropertyDatasourceImpl
. The latter also implements theCollectionDatasource
interface, however some of its irrelevant methods likesetQuery()
throwUnsupportedOperationException
. -
EmbeddedDatasource is a subtype of
NestedDatasource
, which contains an instance of an embedded entity.Standard implementation is the
EmbeddedDatasourceImpl
class.
-
-
RuntimePropsDatasource is a specific datasource, designed to work with dynamic attributes of entities.
Typically, datasources are declared in the dsContext
section of a screen descriptor.
- Automatic CollectionDatasource refresh
-
When the screen opens, its visual components connected to collection datasources cause the datasources to load data. As a result, tables show data right after opening the screen, without any explicit user action. If you want to prevent automatic loading of collection datasources, set the
DISABLE_AUTO_REFRESH
screen parameter totrue
in the screen’sinit()
method or pass it from the calling code. This parameter is defined in theWindowParams
enumeration, so it can be set as shown below:@Override public void init(Map<String, Object> params) { WindowParams.DISABLE_AUTO_REFRESH.set(params, true); }
In this case, the screen collection datasources will be loaded only when their
refresh()
method will be called. It can be done by the application code or when the user clicks Search in the Filter component.