EJB data mediator service programming considerations
When you begin writing your applications to take advantage of the Enterprise JavaBeans (EJB) data mediator service (DMS) provided in the product, consider the following items.
EJB programming model
Only a subset of the
EJB programming model is supported by the EJB data mediator service.
- When using EJB collection parameters to retrieve data from EJB
instances, or when using applyChanges to update EJB instances:
- The EJB DMS uses local interfaces for enterprise beans.
Getter
andsetter
calls for container-managed persistence (CMP) fields must be promoted to the local interface, as well as any EJB methods used in query expressions. - For the mediator to create an EJB, there must be a create method using the primary key class as
the only argument method defined on the EJB home. If no such method exists, you must supply an
adapter that handles the create operation. Also, the EJBLocalHome interface defined for the EJB must
include (in addition to the create method) the following
method:
findByPrimaryKey(<key class>) remove (java.lang.Object) create (<key class>)
- The EJB DMS uses local interfaces for enterprise beans.
- When invoking the applyChanges method directly to the database,
the following occur:
- you bypass container update. You should force a refresh as soon as possible by transaction termination and using appropriate container cache options.
- you bypass EJB container-managed relationship (CMR) maintenance. You must rely on database RI to maintain those relationships not retrieved into the DataGraph.
- CMP fields must be the allowed types. See EJB mediator query syntax for a list of those types.
- CMP fields of user-defined types that use EJB converters/composer are not supported.
The following table shows limitations in the EJB programming model that are not supported by the EJB DMS.
retrieve direct from db | retrieve from EJB Container | update direct to db | update through EJB | |
---|---|---|---|---|
EJB persistence inheritance | No | No | No | No |
EJB cmp field with converter | No | Yes | No | Yes |
Transactional
- All mediator calls, including create, must be done within a transaction scope – either a user transaction or a container transaction. The various mediator calls including, create, getGraph, and applyChanges, do not have to be called within the same transaction. In fact, most often the calls are done in separate transactions.
Access intent
- When the mediator query references an EJB using its abstract schema name (ASN), data is retrieved directly from the database. The access intent and isolation level used on the data source connection is the access intent specified in the application profile for EJB dynamic query access intent. It is recommended that you define an optimistic access intent for your application because a DataGraph is intended to be used in a disconnected programming model.
- When the mediator is retrieving data using an EJB collection, the access intent specified in the application profile is used if the EJB requires activation.
- During applyChanges, optimistic concurrency control is used to verify certain fields in the
DataObject before applying changes to the database. Updates are typically processed under a
different transaction from the retrieval. Therefore, to avoid lost updates it is necessary to verify
that another transaction has not updated the data. When defining the EJB to RDB mapping you can
specify one or more EJB fields as optimistic Predicates. The fields are used for verification by
comparing the current database value to the old value from the DataGraph change log. If the
verification succeeds, then the current value of the fields is written to the database. If the
comparison returns false and the update fails, an exception occurs. All of this is accomplished in a
single update statement with extra predicates added, such as in the following example. The
optimisticPredicate field is
myColumn1
.update myTable set myColumn1="new value1", myColumn2="new value2"where myKey="key value" and myColumn1="old value1"
- When applyChanges is done through the EJB container, the current values of the enterprise beans are compared with the old values of the optimistic predicates fields. If the values are unequal an exception occurs.
- Provided that you have defined one or more EJB fields as optimisticPredicates, then for the SDO to be updateable, at least one of the optmisticPredicate fields must be retrieved into the data object. Otherwise, applyChanges returns an exception. The field should be updated either by the caller or a database trigger – the mediator does not automatically increment or set the field.
- Not all fields are verified, only those fields marked as optimisticPredicate in the EJB-RDB mapping.
- Note that the EJB mapping tool allows for the possibility of no optimisticPredicate fields. In this case the mediator will perform updates without any verification.
- Creation and deletion operations do not make use of the optimistic predicate fields.
- When applying changes through EJB instances, the EJB might have to be activated first. In this case, the appropriate access intent associated with the EJB methods apply. It is recommended that you run applyChanges in a profile that has pessimistic access intent, otherwise the optimistic concurrency logic is invoked twice – once when copying data object values to the EJB, and a second time when the persistence manager compares the old values of the EJB field values against the database record.
- The access intent used by the mediator when retrieving directly from the database is the default access intent defined for the EJB named in the first query statement.
Best practices
- You can call getGraph on one mediator instance, update the returned
DataGraph, and then call applyChanges on a different mediator instance.
However, while they do not need the same mediator instance, they
do need the same
query shape
. The query shape is the number and order of query statements, the fields and relationships specified in the SELECT and FROM clauses, and so on. - Avoid repeated calls to createMediator if possible. Use parameterized queries and use getGraph to pass in different parameter values.