3.6.2.5. DsContext
|
This is a legacy API. For new data API available since release 7.0, see Data Components. |
All datasources that are created declaratively are registered in the DsContext object which belongs to a screen. A reference to DsContext can be obtained using the getDsContext() method of a screen controller or via Controller Dependency Injection.
DsContext is designed for the following tasks:
-
Organizes dependencies between datasources when navigation through a record set in one datasource (i.e. changing a "current" instance with the
setItem()method) causes a related datasource to be updated. These dependencies allow you to organize master-detail relationships between visual components on screens.Dependencies between datasources are organized using query parameters with the
ds$prefix. -
Collects all changed entity instances and sends them to Middleware in a single invocation of
DataManager.commit(), i.e. to save them into the database in a single transaction.As an example, let’s assume that some screen allows a user to edit an instance of the
Orderentity and a collection ofOrderLineinstances belonging to it. TheOrderinstance is located inDatasource; theOrderLinecollection – in nestedCollectionDatasource, which is created using theOrder.linesattribute.If a user changes some attribute of
Orderand creates a new instance,OrderLine, then, when a screen is committed to DataManager, two instances – changedOrderand newOrderLine– will be sent simultaneously. After that, they will together be merged into one persistent context and saved into the database on the transaction commit. It allows you to not specify cascade parameters on the ORM level and avoid the problems mentioned in the @OneToMany annotation description.As a result of committing the transaction,
DsContextreceives a set of saved instances from Middleware (in the case of optimistic locking they, at least, have an increased value of theversionattribute), and sets these instances in datasources replacing old ones. It allows you to work with the latest instances immediately after committing without an extra datasource refresh that produces queries to Middleware and the database. -
Declares two listeners:
BeforeCommitListenerandAfterCommitListener. They receive notifications before and after committing modified instances.BeforeCommitListenerenables to supplement a collection of entities sent to DataManager to save arbitrary entities in the same transaction. A collection of saved instances that are returned fromDataManagercan be obtained after commit in theAfterCommitListenerlistener.This mechanism is required if some entities, with which a screen works, are not under control of datasources, but are created and changed directly in the controller code. For example, a visual component, FileUploadField, after uploading a file, creates a new entity instance,
FileDescriptor, which can be saved together with other screen entities by adding toCommitContextinBeforeCommitListener.In the following example, a new instance of
Customerwill be sent to Middleware and saved to the database together with other modified screen entities when the screen is committed:protected Customer customer; protected void createNewCustomer() { customer = metadata.create(Customer.class); customer.setName("John Doe"); } @Override public void init(Map<String, Object> params) { getDsContext().addBeforeCommitListener(context -> { if (customer != null) context.getCommitInstances().add(customer); } }