Hi Friends,
Here I explain about ADF-Business Component overview and I'll describe for each component in property and details in upcoming blog soon.
Entity objects:
ADF entity object represents a database table and an entity
object instance represents a single row in that table. The entity object
encapsulates application data, validation rules, and persistence logic. Find
below Entity Features, an entity implementation artifacts along with Entity
Runtime behavior details:
Features of Entity:
• Visual and declarative development
• Associations
• Declarative validation
• Entity inheritance
• Entity caching
• Built-in CRUD operations
• Concurrency handling
• Customizable framework components
• Domain-driven development
• Security-enabled business components
Artifacts of Entity:
• Entity
object definition XML metadata file: This file stores the entity object
definition and declarative settings to control the runtime functionality of the
component, stores the database object (database table, view, synonyms, or
materialized view) on which the entity is built upon, stores the attribute
definition like (datatype, length, precision, validation rules, updatability
and UI hints such as label, tool tip, format type, and control type) for each
column present in the entity object. View accessors and entity accessor
attributes' definitions are also stored in this file. View accessors and entity
accessor attributes' definitions are used for accessing view objects and
associated entity objects, respectively, Business event definitions that are
used for launching business processes in a service oriented environment.
• Entity definition: The entity
definition describes the structure of an entity object and acts as a template
for defining the entity instance at runtime. This is generated at runtime,
using the entity object definition XML metadata file. Need to override oracle.jbo.server.EntityDefImpl class
for customizing the default entity definition implementation, and manages
entity row creations and defines their structure. For example, if you want to
modify the properties of an entity object or attributes of an entity object at
runtime, you can override the resolveDefObject() method and add custom logic
for altering the definition before returning to the caller.
• Entity object: An entity object
represents an entity instance, which wraps the business logic for a row in the
data source. We need to override the
oracle.Jbo.server.EntityImpl class
is used for customizing business logic or runtime behavior for entity instance.
• Entity collection: The entity collection
caches queried rows for a particular entity implementation. The entity cache is
associated with the entity object’s held in memory for a transaction (oracle.jbo.server.DBTransaction)
object. In other words, entity rows for a particular entity type share the same
entity cache only if they are participating in the same transaction. The
default entity collection (entity cache) class used by the ADF Business
Components' runtime is oracle.jbo.server.EntityCache,
we can be override it to provide custom functionalities, if needed.
Associations:
Entity object associations define the relation between two
entity objects based on the attributes from each side. Associations are useful
to access the destination entities from a source entity and vice versa. For example,
consider a department and an employee as entity objects. A department can have
many employees. This relation can be represented by using association. The
number of elements in each side of the association is decided by the
cardinality property. When you define association, IDE generates access or
attributes in entities participating in association. These attributes can be
used for accessing related entities.
Runtime Behavior of
Entity:
At runtime, when an entity instance is created, the
framework uses corresponding entity definition class for defining the entity
structure. All entity instances inherit the properties from its entity
definition class. When the primary key is set for a newly created entity
instance, it qualifies for being stored in the entity collection (entity
cache). The framework will access the entity instance from the cache
thereafter.
View objects:
An ADF view object contains logic for reading data from a
data source. It fetches a row set from a data source and shapes each attribute
in a row for presenting them to the client. View objects can be built based on
entity objects, a SQL query, or a static list. We see the View Object features,
artifacts and runtime behavior below:
View object features:
• Visual and declarative development
• Read-only and updatable view objects
• Automated master-child co-ordination
• Domain-driven development
• Query-by-example support
• Caching of result set
• Out-of-the-box pagination support
• Built-in CRUD operations
• Polymorphic view objects
• Declarative settings for fine-tuning
runtime performance
• Customizable framework components
• Scalable architecture through
out-of-the-box support for activation and passivation cycles
View objet Artifacts:
• View
object definition XML metadata file: The view object definition is stored
in this file, which contains the query, Bind parameter definitions, and Attribute
definition describing each column returned by the query—this includes
UI-related metadata, such as UI Hints and UI Categories for attributes definition
of each row in the data source, Entity usage information, Metadata definition
for list of values (LOV) and view criteria (query), View accessor and Business
rules.
• View object definition: The view object
definition acts as a Java wrapper for the XML metadata file. The default view
definition class used by the ADF Business Components' runtime is oracle.jbo.server.ViewDefImpl, which
can be extended to provide custom functionalities, if required.
• View object: The view object instance
manages the query execution life cycle. To intercept the query execution and
data population logic, we can override the (oracle.jbo.server.ViewObjectImpl) class methods provided by the
framework.
• View criteria: View criteria will let
you define filter conditions for attributes in a view object, which will be
used at runtime to filter the query result.
This implementation takes the form of a query-by-example
approach, which allows the end user to supply values for attributes of the
target view object in order to form the desired search condition.
• Where Clause: we can apply the where
clause as well to filter the record but this we need to define in the query
itself.
• Bind variables: These are placeholder
variables in a SQL statement used in a view object. These variables will be
replaced with the valid ones before executing the query.
Note: we can
apply the View Criteria and where clause in the View Object Query
Programmatically also at run time; and bind variables will be available in view
object class not in view row class; we’ll discuses about this in next blog.
• View accessor: This acts as a gateway
for a view object to access another view object. This is used in validation and
LOV definitions.
A view object uses the following framework components to set
up the infrastructure for query execution and managing the result set:
• Row:
A row represents an element in the collection that is a result from a query on
a view object, we can override the View Object Row via extending the class oracle.jbo.server.Row to customized the
attribute row value.
• Row
set: A view object can have multiple row sets (collection of rows from a
query.). The framework will create a different row set when the same view
object is used as a mechanism to query the data source in different contexts.
The primary row set used by a view object is termed as default row set. When a view object is executed, by default, it
uses the primary row set to hold the rows. The other row sets, which are created
explicitly by the client, are secondary
row sets.
• Row set iterator: This enables the
client to traverse the row set and work with individual items. A client can
create one or more row set iterators to enumerate through the rows.
• Query collection: The query collection
caches the result of executing a view object. A view object instance may
contain multiple query collections, depending on the parameter values used by
the row sets to execute the parameterized query. All the row sets in a view object
are backed up by query collection objects. If two or more row sets use the same
parameter values to execute the query, the framework will share the same query
collection object to store the rows for those row sets.
Note: A row or
row set does not store any data within it, rather they use query collection
object for storing rows.
• View link: ADF view links define the
relation between view objects. A view link will help you to access the row set
present in the destination view object from the source view row and vice versa.
View links are defined by mapping attributes of the view object to attributes
of a depended view object. If the view object is built using entity objects,
the view link can also be defined by choosing the association definition that
exists between underlying entity objects. View link is useful for building a
master-detail UI.
Runtime Behavior of
View objects when fetching the data:
A view object may contain multiple row sets and among these,
some row sets might have used the same parameter values for executing the
query. While it is necessary to keep the logic for navigation cases and
pagination specific to each client, there is no need to replicate the same
collection across row sets, if they have queried the database with the same
parameter values. So, the framework uses query collection instances to cache
the rows from query execution serving multiple row sets with the same bind
variable values.
Example:
We’ll use hr schema in this example with DepartmentVO and
EmployeeVO with viewlink relationship with manager Id attribute.
Scenario: (note need to update the data with manager Id 201
in department 10 to understand this example); department 10 we are having
manager Id 201 and department 20 we are having manager Id 201; under this manager
only 1 employee (202) is working and in department 30 we are having manager Id
114; under him only 5 employees (115 to 119) are working.
Now, when you query the DepartmentVO view object, the
framework populates the default row set in the DepartmentVO view object with
department Id 10, 20, and 30 and so on; but when the application invokes the
view link accessor to get the Employees from DepartmentVO, each department row
will produce a view row set in the EmployeeVO view object. As all collections
need to co-exist at this stage, the framework does not touch the default row set;
it rather generates a secondary row set in the supplier view object to hold the
collection for each caller. Department 10 and 20 show EmployeeList under
Manager Id 201, and Department 30 shows the EmployeeList under manager Id 114.
As the first two view row sets show the same data, the
framework will re-use the same query collection for Manager Id='201', and the
third will have its own query collection for Manager Id='114' as illustrated in
the following diagram:
ADF Business Components work together and complement each
other to read data from a datasource. View object queries the datasource and
populates the row set. The following code snippet will help you to query the
DEPARTMENTS table through the DepartmentVO view object.
ViewObject
vo = applicationModule.findViewObject("DepartmentVO"); // to find the
View Object
vo.execute();
//execute view object to fetch rows
Row
row=vo.first(); //Move to the first row in the row set
The client
then executes executeQuery() on the view object instance to initiate the data
fetch operation. The view object instance does not directly query the database;
rather it acts as the primary contact point for client. The view object finds
the default row set and delegates the call. The row set, as the name suggests,
is responsible for managing the row collection for the client. When any view
object calls executeQuery() on a row set, it does the following tasks:
• Row set will check the associated view
object instance to see if a query collection for the search parameters (row
filter) is already available. If yes, use the same query collection object.
• If it does not exist, then a new query
collection will be created and this will be added to the view object.
Once the
query collection is initialized, the row set will engage the standard query
execution lifecycle methods from the view object. The row set instance calls
prepareRowSetForQuery() on the view object first. This callback method is the
place to hook your custom code (if any) right before the query execution. This
is followed by a call to executeQueryForCollection() on the view object. The
view object delegates the call to the query collection instance.
When the
client tries to get the first row in the result set by calling first() on the
view object instance, the call will reach the default row set instance in the
view object. The row set will now initialize the default row set iterator
object, which is responsible for iteration over the view row collection. As the
row set is not yet populated with rows, call for the first element by the
iterator will put the associated query collection instance into action. The
query collection will start serving the call by checking whether the result set
from the query has any rows to work on, and if this check returns true, it
starts generating a view row for the first item in the result set.
What happen when we execute the entity based view object:
While
creating the row, if the view object definition is based on an entity object,
entity instances will be created and added to corresponding entity cache.
The next step is to populate the newly created entity
instances with values from the row in the result set. If there is an entity
backup, each row in the query collection will simply act as pointers to
corresponding entity instances, and actual data will be present in the entity
cache. Once the row is created and storage for the row is set pointing to the
entity object, it will be added to the query collection's internal list. If the
view object is not built using entity objects, obviously the entity cache would
be missing and each row in query collection will be holding the data.
Transaction post
cycle for business components while committing the data:
The following code snippet used in this example to fetches a
row from the DEPARTMENTS table by using the DepartmentVO and modifies
DepartmentName in the row. The commit() call on the transaction makes changes
to the database.
ViewObject
vo = applicationModule.findViewObject("DepartmentVO");
vo.executeQuery();
Row deptRow
= vo.first(); //Modify the attribute DepartmentName for first row
deptRow.setAttribute("DepartmentName",
"HR Service"); //Commit the transaction
applicationModule.getTransaction().commit();
When you
modify the attribute value by calling setAttribute() on a row, the call reaches
the underlying entity instance on which the row is based. At this stage, the
following actions happen:
• The framework pushes the modified attribute
value to the entity instance.
• Then, marks it as modified.
Runtime adds
the modified entity instance to the transaction listener list and to the
validation listener list, maintained by the DBTransaction object attached to
the owning application module. Later, when you commit changes by calling
commit() on a transaction, the following steps are triggered behind the scenes:
• The DBTransaction
object triggers the validate phase. All the modified entities that are
available in the validation listener list are validated.
• Transaction
manager starts the data post cycle. All the newly created, deleted, and
modified entities that were added into the transaction post listener list will
be participating in this cycle. During the post changes cycle, the framework
performs the following tasks:
°
Locks each modified entity
°
Generates native SQL for data manipulation based on the type of
operation and modified attributes
°
Executes JDBC statements, which post modified data to the database
• The last step is committing the
transaction. Runtime makes pre- and post-callbacks to enable all the parties
participating in the transaction to perform any actions before and after the
transaction commits.
Application modules:
Application module acts as a service layer for the business
services built, using business components. It represents a modular unit of
work, and exposes the data model and business method to be used by the client.
As the application module is the first layer that a client interacts with, the
framework takes special care to reduce the cost associated with the creation
and destruction of instances by enabling instance pooling for application
modules. Instance pooling reduces the number of application module instances,
and thereby the resources needed by service client requests. You can use
various configuration parameters to control the pool behavior at runtime. Here
we list-out some basic features, along with artifacts.
Features of
Application Module:
• Visual and declarative development.
• Improved modularity support for the
business services.
• Out of the box support for basic
infrastructure services required for an enterprise application. The list
includes management of user sessions, business transactions, database
connections, and concurrent access.
• Support to nest multiple application
modules to build composite services.
• Declarative settings to fine-tune runtime
performance.
• Runtime monitoring and tuning support.
• Scalable architecture through out of the box
support for instance pooling.
• Cluster aware components which ensure the
high availability for the system.
• Ability to expose the service methods as
web services for use by heterogeneous clients.
An application module is composed of the
following parts:
• Application module definition XML metadata
file: The application module definition metadata is stored in this XML file;
which includes exposed business methods and data models for use, by clients,
such as view objects and associated view criteria, master-child view, objects
connected through view links, and nested application modules.
• Application module definition: The
application module definition acts as a Java wrapper for the XML metadata file,
which will be used at the runtime to create application module instances, can
customize this via extending the class oracle.jbo.server.ApplicationModuleDefImpl.
• Application module: This is an
application module instance, which exposes the data model to be used by a
client; an application module instance is a work unit container, which
aggregates the following component instances and methods:
• View object instances: These are the
instances exposed to the client to use.
• View link instances: View link
instances are used to connect view object instances in an application module.
Whenever the currently selected row is changed on the master view object
instance, the detail view object will be refreshed with new set of rows for the
new parent. View link instances are built by using the view links defined
between view object definitions.
• Custom business methods: These are
methods exposed by an application module that implements the business logic
that can be used by client.
Note: To write
the custom business methods and for any custom functionality we need to extend
the oracle.jbo.server.ApplicationModuleImpl
class and then need to expose the custom business methods to the client
Interface to use in UI Layer and these method must execute in the application's
middle tier.
• Nested application module: An application
module can act as a composite root application module by nesting existing
application modules. This feature is useful for composing services to be used
by a client.
• bc4j.xcfg: This file contains metadata
for all the application modules present in the same Java package for a project.
This file is located in the Common subdirectory relative to the path where the
application module's XML component definition is located. An application
module's runtime behavior is controlled by the configuration properties present
in this file. The properties stored in this file include the JDBC data source
name, application module pooling configurations, database specific
configurations, locking mode, and so on.
• Application Pool: The application pool
is responsible for managing the instance's pool for a specific application
module. The default implementation class used by runtime is
oracle.jbo.common.ampool.ApplicationPoolImpl
• Connection Policy: Application pool
makes use of this component for creating new application module instances and
also for connecting an application module with a data source. The default
implementation used by the run time is
oracle.jbo.common.ampool.DefaultConnectionStrategy. To provide a custom
connection strategy class, need to override the jbo.ampool.connectionstrategyclass
property in the bc4j.xcfg file by setting it to the fully qualified name of the
custom connection strategy class.
• Session: The session object stores the
session context for the client. A session object is instantiated for each root
application module when the application module is activated. The default
session implementation class is oracle.jbo.server.SessionImpl. To provide a
customized session implementation class, override the SessionClass property in
the bc4j.xcfg file by setting it to the fully qualified name of the custom
session class.
• Transaction Handler: This handles the
database transaction associated with the user session. To override the default
transaction handler (oracle.jbo.server.DefaultTxnHandlerImpl), you will have to
implement oracle.jbo.server.TransactionHandlerFactory that returns a custom
oracle.jbo.serverTransactionHandler implementation.
To make the application module to use your
customTransactionHandlerFactory, customize the oracle.jbo.server.SessionImpl by
overriding the SessionImpl::getTransactionHandlerFactory() method to return the
custom TransactionHandlerFactory implementation that you created.
Services and service
data objects (Service enabled Application Module)
An
application module can be easily extended as web service by using the
design-time support provided by JDeveloper. The application module editor
allows you to expose application modules as web services that use Service Data
Object (SDO) components based on the view instance defined in the application
module. The service-enabled application module exposes the view object
instances, custom business methods, built-in data manipulation operations, and
find methods to be used by the client.