Sie sind auf Seite 1von 18

Most Commonly Used Methods in ADF Business

Components
Author: Steve Muench, ADF Development Team
Date: January 19, 2006
Revision 1.9 ( Revision History)
Abstract
This paper provides a high-level description of the key ADF Business Components classes in the Oracle
Application Development Framework, summarizing the methods that ADF developers write, call, and override
most frequently.

Contents
Overview
Logical Architecture of Services Built with ADF Business Components
Most Commonly Used Methods in the Client Tier
ApplicationModule Interface
Transaction Interface
ViewObject Interface
RowSet Interface
RowSetIterator Interface
Row Interface
StructureDef Interface
AttributeDef Interface
AttributeHints Interface
Most Commonly Used Methods In the Business Service Tier
Controlling Custom Java Files For Your Components
ApplicationModuleImpl Class
DBTransactionImpl2 Class
EntityImpl Class
EntityDefImpl Class
ViewObjectImpl Class
ViewRowImpl Class
Setting Up Your Own Layer of Framework Base Classes
Conclusion
Overview
Service-oriented J2EE Applications built using the ADF framework encapsulate their business logic into one or
more business services. Clients access these business services either as web services or, when the client is a
user interface, using the ADF data-binding layer that implements the Data Controls and Bindings from JSR-227.
The data controls abstract the back-end business service implementations and binding objects link front-end user
interface controls in a declarative way to back-end data.
ADF supports business services implemented as simple Java objects, web services, EJB Session beans, and
framework-based Java objects that inherit built-in functionality from the ADF Business Components base classes.
These ADF Business Components are business-tier building-block classes, and related design-time extensions
to JDeveloper, that give you a prescriptive architecture for building richly-functional and cleanly layered J2EE
business services with great performance. This paper offers a high-level description of the key components that
comprise ADF Business Components, and provides a summary of the methods that developers leveraging ADF
BC base classes write, call, and override most frequently while building their J2EE-compliant business services.
Logical Architecture of Services Built with ADF Business Components
You can use business services you build with ADF Business Components in one of three ways:
1.
2.
3.

As lightweight local Java service classes,


As EJB session beans, or
As stateless web services
In all three cases, there is a clean separation between the client tier code that invokes the service and the
business service tier where the service's implementation details reside.

With the J2EE web service option, your web service client interacts with the service using a web service proxy
class generated by the client tool environment based on the service's WSDL service description. The methods
that appear on your web service are the custom methods you've written on your business service component.
With the local Java service class and the EJB session bean options, your Java client code interacts with either
the base ADF component interfaces or custom component interfaces that JDeveloper 10g generates for you
automatically after indicating which custom methods should appear on the component's client interface.
Since ADF adopts this best-practice approach of having your client work with interfaces instead of directly with
implementation classes, it offers the additional benefit of allowing you to change between deploying your
business service as a local Java class or an EJB session bean without changing your client code. Along with the
custom service interface, JDeveloper generates appropriate client-side proxy implementation classes that
implement your custom interface. As such, it's an implementation detail you don't need to worry about yourself.
With either 2-tier or 3-tier deployment of your application modules, thing just work...which is nice.
Figure 1 shows the relationships between the key components in the Oracle Application Development
Framework. The dashed vertical line in the diagram represents the clean separation of component interfaces that
are available on the client, and which ones are only available in the business tier implementation.

Figure 1: Relationship Between Key ADF Business Components Classes


Whenever you deploy an ADF Business Components project using a Business Components deployment profile
in JDeveloper 10g, two separate JAR files get created, further emphasizing this logical separation between
business tier and client tier:

YourProjectNameCSMT.jar
This archive contains all of the implementation classes that comprise your project's business service application
module components and other ADF BC components that your application modules use. We picked the MT suffix
in the name to represent Middle Tier. When deploying your application module as an EJB Session Bean, this JAR
file lives on the EJB middle tier. It never is downloaded to the remote client.

YourProjectNameCSCommon.jar
This archive contains any custom client interfaces, generated custom remote client proxy classes, custom
domains, and message bundles that are accessible by both the client-tier and the business service tier. We
picked the suffix Common in the archive name to remind you that this jar is common to both tiers. This file is
generally relatively quite small compared to the middle-tier JAR.
The following sections briefly explain each component and give tips about the methods J2EE developers using
ADF Business Components will use most frequently for each kind of component.
Most Commonly Used Methods in the Client Tier

All of the interfaces described in this section are designed for use by client-layer code and are part of
the oracle.jbo.* package.
NOTE:

The corresponding implementation classes for these oracle.jbo.* interfaces are consciously designed to not be directly a

client code. As we'll see in the Most Commonly Used Methods In the Business Service Tier section below, the implementation

in the oracle.jbo.server.* package and generally have the suffix Impl in their name to help remind you not to using the
client-layer code.

ApplicationModule Interface
The ApplicationModule

is a business service component that acts as a transactional container for

other ADF components and coordinateswith them to implement a number of J2EE design patterns important to
business application developers. These design pattern implementations enable your client code to work easily
with updateable collections of value objects, based on fast-lane reader SQL queries that retrieve only the data
needed by the client, in the way the client wants to view it. Changes made to these value objects are
automatically coordinated with your persistent business domain objects in the business service tier to enforce
business rules consistently and save changes back to the database.

If you want
to...

Call this ApplicationModule interface method...

findViewObject()
Access an
existing view
object instance
by name
Creating a new createViewObject()
view object
instance from an
existing definition
Creating a new createViewObjectFromQueryStmt()
view object
instance from a Note This incurs runtime overhead to describe the "shape" of the dynamic query's SELECT list.
SQL Statement :
We recommend using this only when you cannot know the SELECT list for the query at
design-time. Furthermore, if you are creating the dynamic query based on some kind of
custom runtime repository, you can follow this tip to create (both read-only and
updateable) dynamic view objects without the runtime-describe overhead with a little more
work. If only the WHERE needs to be dynamic, create the view object at design time, then
set the where clause dynamically as needed using
ViewObject
API's.
Access a nested findApplicationModule()
application
module instance
by name
createApplicationModule()
Create a new
nested
application
module instance
from an existing
definition
Find a view
findViewObject()
object instance in
a nested
Note To find an instance of a view object belonging to a nested application module you use a
application
:
dot notationnestedAMInstanceName.VOInstanceName
module
getTransaction()
Accessing the
current
transaction
object
In addition to generic ApplicationModule access, JDeveloper 10g can generate you a
custom YourApplicationModuleNameinterface containing service-level custom methods that you've chosen
to expose to the client. You do this by visiting the Client Interface tab of the Application Module editor, and
shuttling the methods you'd like to appear in your client interface into the Selected list. JDeveloper will also

generate an appropriate YourApplicationModuleNameClientclient proxy implementation class that is


used automatically by your remote client in the case that you deploy your application module as an EJB Session
Bean or whenever you use your application module in Batch Mode.
Transaction Interface
The Transaction
interface exposes methods allowing the client to manage pending changes in the
current transaction.

If you want to...

Call this Transaction interface method...

commit()
Commit pending
changes
Rollback pending rollback()
changes
Execute a one-time executeCommand()
database command
or block of PL/SQL Note Commands that require retrieving OUT parameters, that will be executed more than
:
once, or that could benefit by using bind variables should not use this method. Instead,
expose a custom method on your application module class as described here.
Validate all pending validate()
invalid changes in
the transaction
Change the default setLockingMode()
locking mode
Note You can set the locking mode in your configuration by setting the
:
property jbo.locking.mode to one of the four supported
values: none, optimistic, pessimistic, optupdate. If you don't explicitly set it, it
will default to pessimistic. For web applications, we recommend
using optimistic or optupdate modes.
Decide whether to setBundledExceptionMode()
use bundled
exception reporting Note ADF controller layer support sets this parameter to true automatically for web
mode or not.
:
applications.
Decide whether
setClearCacheOnCommit()
entity caches will be
cleared upon a
Note:
Default is false
successful commit
of the transaction.
Decide whether
setClearCacheOnRollback()
entity caches will be
cleared upon a
Note:
Default is true
rollback of the
transaction.
clearEntityCache()
Clear the entity
cache for a specific
entity object.
ViewObject Interface
A ViewObject
encapsulates a database query and simplifies working with the
RowSet
of results it
produces. You use view objects to project, filter, join, or sort business data using SQL from one or more tables
into exactly the format that the user should see it on the page or panel. You can create "master/detail" hierarchies
of any level of depth or complexity by connecting view objects together using view links. View objects can
produce read-only query results, or by associating them with one ore more entity objects at design time, can be
fully updateable. Updateable view objects can support insertion, modification, and deletion of rows in the result
collection, with automatic delegation to the correct business domain objects.
Every ViewObject aggregates a "default rowset" for simplifying the 90% of use cases where you work with a
single
RowSet
of results for theViewObject's query. A ViewObject implements all the methods on
the RowSet interface by delegating them to this default RowSet. That means you can invoke
any
RowSet
methods on any ViewObject as well.
Every ViewObject implements the
StructureDef
interface to provide information about the number and types
of attributes in a row of its rowsets. So you can call StructureDef methods right on any view object.

If you want to...

Call this ViewObject interface method...

Set an additional runtime setWhereClause()

WHERE clause on the


rowset
Set a dynamic ORDER
BY clause
Create a Query-byExample criteria
collection

Note This WHERE clause augments any WHERE clause specified at design time in the
:
base view object. It does not replace it.
setOrderByClause()
createViewCriteria()
Note You then create one or more ViewCriteriaRow objects using
:
the createViewCriteriaRow()method on the ViewCriteria object you
created. Then, you add() these view criteria rows to the view criteria collection
and apply the criteria using the method below.
applyViewCriteria()

Apply a Query-byExample criteria


collection
Set a query optimizer hint setQueryOptimizerHint()
getKeyAttributeDefs()
Access the attribute
definitions for the key
attributes in the view
object
Add a dynamic attribute addDynamicAttribute()
to rows in this view
object's rowsets
clearCache()
Clear all rowsets
produced by a view object
remove()
Remove view object
instance an its resources
Set an upper limit on the setMaxFetchSize()
number of rows that the
view object will attempt to Note
Default is -1 which means to impose no limit on how many rows would be
fetch from the database. :
retrieved from the database if you iterate through them all. By default they are
fetched lazily as you iterate through them.

In addition to generic ViewObject access, JDeveloper 10g can generate you a


custom YourViewObjectNameinterface containing view-object level custom methods that you've chosen to
expose to the client. You do this by visiting the Client Interface tab of the View Object editor, and shuttling the
methods you'd like to appear in your client interface into the Selected list. JDeveloper will also generate an
appropriateYourViewObjectNameClientclient proxy implementation class that is used automatically by your
remote client in the case that you deploy your application module as an EJB Session Bean or whenever you use
your application module in Batch Mode.
RowSet Interface
A RowSet
is a set of rows, typically produced by executing a ViewObject's query.
Every RowSet aggregates a "default rowset iterator" for simplifying the 90% of use cases where you only need a
single iterator over the rowset. A RowSet implements all the methods on the RowSetIterator interface by
delegating them to this default RowSetIterator. This means you can invoke any
RowSetIterator
method
on any RowSet (or ViewObject, since it implements RowSet as well for its default RowSet).

If you want to...


Set a where clause bind
variable value

Call this RowSet interface method...


setWhereClauseParam()
Note:

Bind variable ordinal positions are zero-based

Avoid view object row caching setForwardOnly()


if data is being read only once
Force a rowset's query to be executeQuery()
(re)executed
Estimate the number of rows in getEstimatedRowCount()
a view object's query result
writeXML()
Produce XML document for
rows in View Object rowset
readXML()
Process all rows from an
incoming XML document
setAssociationConsistent()
Set whether rowset will
automatically see new rows

based on the same entity


object created through other
rowsets
Create secondary iterator to createRowSetIterator()
use for programmatic iteration
Note If you plan to find and use the secondary iterator by name later, then pass in
:
a string name as the argument, otherwise pass null for the name and
make sure to close the iterator when done iterating by calling
its closeRowSetIterator() method.
RowSetIterator Interface
A RowSetIterator
is an iterator over the rows in a RowSet. By default it allows you to iterate both
forward and backward through the rows.

If you want to...


Get the first row of the
iterator's rowset
Test whether there are
more rows to iterate
Get the next row of
iterator's rowset
Find row in this iterator's
rowset with a given Key
value

Create a new row to


populate for insertion

Call this RowSetIterator interface method...


first()
hasNext()
next()
findByKey()
Note It's important that the Key object that you pass to findByKey be created using
:
the exact same datatypes as the attributes that comprise the key of the rows in
the view object you're working with.
createRow()
Note The new row will already have default values set for attributes which either have
:
a static default value supplied at the entity object or view object level, or if the

values have been populated in an overriddencreate() method of the


underlying entity object(s).
Create a view row with an createAndInitRow()
initial set of foreign key
and/or discriminator
Note You use this method when working with view objects that can return one of a
attribute values
:
"family" of entity object subtypes. By passing in the correct discriminator attribute
value in the call to create the row, the framework can create you the correct
matching entity object subtype underneath.
Insert a new row into the
iterator's rowset

insertRow()
Note It's a good habit to always immediately insert a newly created row into the
:
rowset. That way you will avoid a common gotcha of creating the row but
forgetting to insert it into the rowset.

last()
Get the last row of the
iterator's rowset
previous()
Get the previous row of
the iterator's rowset
reset()
Reset the current row
pointer to the slot before
the first row
closeRowSetIterator()
Close an iterator when
done iterating
Set a given row to be the setCurrentRow()
current row
Remove the current row removeCurrentRow()
Remove the current row to removeCurrentRowAndRetain()
later insert it at a different
location in the same
iterator.
Remove the current row removeCurrentRowFromCollection()
from the current collection
but do not remove it from

the transaction.
Set/change the number of setRangeSize()
rows in the range (a
"page" of rows the user
can see)
Scroll to view the Nth page scrollToRangePage()
of rows (1-based)
Scroll to view the range of scrollRangeTo()
rows starting with row
number N
Set row number N in the setCurrentRowAtRangeIndex()
range to be the current
row
Get all rows in the range getAllRowsInRange()
as a Row array
Row Interface
A Row
is generic value object. It contains attributes appropriate in name and Java type for
the ViewObject that it's related to.

If you want to...

Call this Row interface method...

getAttribute()
Get the value of an attribute by name
setAttribute()
Set the value of an attribute by name
writeXML()
Produce an XML document for a single row
validate()
Eagerly validate a row
readXML()
Read row attribute values from XML
remove()
Remove the row
Flag a newly created row as temporary (until updated again) setNewRowState(Row.STATUS_INITIALIZED)
Retrieve the attribute structure definition information for a rowgetStructureDef()
getKey()
Get the Key object for a row
In addition to generic Row access, JDeveloper 10g can generate you a
custom YourViewObjectNameRowinterface containing your type-safe attribute getter and setter methods, as
well as any desired row-level custom methods that you've chosen to expose to the client. You do this by visiting
the Client Row Interface tab of the View Object editor, and shuttling the methods you'd like to appear in your
client interface into theSelected list. JDeveloper will also generate an
appropriate YourViewObjectNameRowClientclient proxy implementation class that is used automatically by
your remote client in the case that you deploy your application module as an EJB Session Bean or whenever you
use your application module in Batch Mode.
StructureDef Interface
A StructureDef
is an interface that provides access to runtime metadata about the structure of a
Row
.
In addition, for convenience every ViewObject implements the StructureDef interface as well, providing
access to metadata about the attributes in the resulting view rows that its query will produce.

If you want to...

Call this StructureDef interface


method...

Access attribute definitions for all attributes in the view object getAttributeDefs()
row
findAttributeDef()
Find an attribute definition by name
getAttributeDef()
Get attribute definition by index
getAttributeCount()
Get number of attributes in a row
AttributeDef Interface
An AttributeDef
provides attribute definition information for any attribute of a View Object row or
Entity Object instance like attribute name, Java type, and SQL type. It also provides access to custom attributespecific metadata properties that can be inspected by generic code you write, as well as UI hints that can assist
in rendering an appropriate user interface display for the attribute and its value.

If you want to...

Call this AttributeDef interface method...

Get the Java type of getJavaType()


the attribute
Get the SQL type of getSQLType()
the attribute
Note: The int value corresponds to constants in the JDBC class java.sql.Types
Determine the kind getAttributeKind()
of attribute
Not If it's a simple attribute, it returns one of the

e: constants ATTR_PERSISTENT, ATTR_SQL_DERIVED,ATTR_TRANSIENT, ATTR_DYNAM


IC, ATTR_ENTITY_DERIVED. If it is an 1-to-1 or many-to-1 association/viewlink
accessor it returns ATTR_ASSOCIATED_ROW. If it is an 1-to-many or many-to-many
association/viewlink accessor it returns ATTR_ASSOCIATED_ROWITERATOR
Get the Java type of getElemJavaType()
elements contained
in anArray-valued
attribute
Get the SQL type of getElemSQLType()
elements contained
in anArray-valued
attribute
Get the name of the getName()
attribute
getIndex()
Get the index
position of the
attribute
Get the precision of getPrecision()
a numeric attribute
or the maximum
length of a String
attribute
Get the scale of a getScale()
numeric attribute
Get the underlying getColumnNameForQuery()
column name
corresponding to the
attribute
Get attribute-specific getProperty(), getProperties()
custom property
values
getUIHelper()
Get the
UIAttributeHint
s object for the
attribute
isMandatory()
Test whether the
attribute is
mandatory
isQueriable()
Test whether the
attribute is queriable
isPrimaryKey()
Test whether the
attribute is part of
the primary key for
the row
AttributeHints Interface
The AttributeHints
interface related to an attribute exposes UI hint information that attribute that you
can use to render an appropriate user interface display for the attribute and its value.

If you want to...


Get the UI label for the attribute
Get the tool tip for the attribute
Get the formatted value of the attribute, using any format
mask supplied
Get the display hint for the attribute

Call this AttributeHints interface


method...
getLabel()
getTooltip()
getFormattedAttribute()
getDisplayHint()
Note Will have a String value of
:
either Display or Hide.
getControlType()
parseFormattedAttribute()

Get the preferred control type for the attribute


Parse a formatted string value using any format mask
supplied for the attribute
Most Commonly Used Methods In the Business Service Tier
The implementation classes corresponding to the oracle.jbo.* interfaces described above are consciously
designed to not be directly accessed by client code. They live in a different package

named oracle.jbo.server.* and have the Impl suffix in their name to help remind you not to using them in
your client-layer code.
In your business service tier implementation code, you can use any of the same methods that are available to
clients above, but in addition you can also:

Safely cast any oracle.jbo.* interface to its oracle.jbo.server.* package implementation class
and use any methods on that Impl class as well.
Override any of the base framework implementation class' public or protected methods to augment
or change its default functionality by writing custom code in your component subclass before or after
calling super.methodName().
This section provides a summary of the most frequently called, written, and overridden methods for the key ADF
Business Components classes.
Controlling Custom Java Files For Your Components
Before examining the specifics of individual classes, it's important to understand how you can control which
custom Java files each of your components will use. When you don't need a customized subclass for a given
component, you can just let the base framework class handle the implementation at runtime.
Each business component you create comprises a single XML component descriptor, and zero or more related
custom Java implementation files. Each component that supports Java customization has a Java tab in its
component editor in the JDeveloper 10g IDE. By checking or unchecking the different Java classes, you control
which ones get created for your component. If none of the boxes is checked, then your component will be an
XML-only component, which simply uses the base framework class as its Java implementation. Otherwise, tick
the checkbox of the related Java classes for the current component that you need to customize. JDeveloper 10g
will create you a custom subclass of the framework base class in which you can add your code.
NOTE:You can setup global IDE preferences for which Java classes should be generated by default for each
ADF business component type by selecting Tools | Preferences... | Business Components and ticking
the checkboxes to indicate what you want your defaults to be.

A best practice is to always generate Entity Object and View Row classes, even if you don't require any custom
code in them other than the automatically-generated getter and setter methods. These getter and setter methods
offer you compile-time type checking that avoids discovering errors at runtime when you accidentally set an
attribute to an incorrect kind of value.
ApplicationModuleImpl Class
The ApplicationModuleImpl
class is the base class for application module components. Since the
application module is the ADF component used to implement a business service, think of the application module
class as the place where you can write your service-level application logic. The application module coordinates
with view object instances to support updateable collections of value objects that are automatically "wired" to
business domain objects. The business domain objects are implemented as ADF entity objects.
Methods You Typically Call on ApplicationModuleImpl

If you want to...

Call this method of the ApplicationModuleImpl class

Perform any of the common


See the ApplicationModule Interface section above.
application module operations from
inside your class, which can also be
done from the client
getViewObjectInstanceName()
Access a view object instance that
you added to the application module's
data model at design time
Note JDeveloper 10g generates this type-safe view object instance getter
:
method for you to reflect each view object instance in the application
module's design-time data-model.
getDBTransaction()
Access the current DBTransaction
object
Access a nested application module getAppModuleInstanceName()
instance that you added to the
application module at design time
Note JDeveloper 10g generates this type-safe application module instance

getter method for you to reflect each nested application module


instance added to the current application module at design time.

Methods You Typically Write in Your Custom ApplicationModuleImpl Subclass

If you want to...


Invoke a database stored
procedure

Write a method like this in your custom ApplicationModuleImpl


class
someCustomMethod()
Note Use appropriate method on the
DBTransaction
interface to create a
:
JDBC PreparedStatement. If the stored procedure has OUT parameters,

Expose custom business


service methods on your
application module

then create a CallableStatement instead.


See this sample project for a robust code example of encapsulating a call to a
PL/SQL stored procedure inside your application module.
someCustomMethod()
Note Select the method name on the Client Interface panel of the application
:
module editor to expose it for client access if required.

JDeveloper 10g can generate you a custom YourApplicationModuleNameinterface containing service-level


custom methods that you've chosen to expose to the client. You do this by visiting the Client Interface tab of the
Application Module editor, and shuttling the methods you'd like to appear in your client interface into
the Selected list.
Methods You Typically Override in Your Custom ApplicationModuleImpl Subclass

If you want to...

Override this method of the ApplicationModuleImpl class

Perform custom setup prepareSession()


code the first time an
application module is Note
This is the method you'd use to setup per-client context info for the current user in
created and each
:
order to use database Oracle's Virtual Private Database (VPD) features. It can also
subsequent time it gets
be used to set other kinds of PL/SQL package global variables, whose values might
used by a different
be client-specific, on which other stored procedures might rely.
client session.
This method is also useful to perform setup code that is specific to a given view
object instance in the application module. If instead of being instance-specific you
want the view object setup code to be initialized for every instance ever created of
that view object component, then put the setup logic in an
overridden create() method in your ViewObjectImpl subclass instead.
Perform custom setup afterConnect()
code after the
application module's
Note Can be a useful place to write a line of code that
transaction is
:
uses getDBTransaction().executeCommand()to perform an ALTER
associated with a
SESSIONSETSQLTRACETRUE to enable database SQL Trace logging for the
database connection
current application connection. These logs can then be processed with
from the connection
pool.
the
TKPROF
utility to study the SQL statements being performed and the query
optimizer plans that are getting used.
Perform custom setup beforeDisconnect()
code before the
application module's
Note If you have set jbo.doconnectionpooling to true, then the connection is
transaction releases its :
released to the database connection pool each time the application module is
database connection
returned to the application module pool.
back to the database
connection pool.
passivateState()
Write custom
application module
state to the state
management XML
snapshot
activateState()
Read and restore

custom application
module state from the
state management XML
snapshot
DBTransactionImpl2 Class
The DBTransactionImpl2

class which extends the base


DBTransactionImpl
class, and is

constructed by theDatabaseTransactionFactory

class is the base class that implements


the
DBTransaction
interface, representing the unit of pending work in the current transaction.
Methods You Typically Call on DBTransaction

If you want to...

Call this method on


the DBTransaction
object

commit()
Commit the transaction
rollback()
Rollback the transaction
validate()
Eagerly validate any pending invalid changes in the
transaction
Create a JDBC PreparedStatement using the transaction's createPreparedStatement()
Connection object
Create a JDBC CallableStatement using the transaction's createCallableStatement()
Connection object
createStatement()
Create a JDBC Statement using the transaction's
Connection object
addWarning()
Add a warning to the transaction's warning list.
Methods You Typically Override in Your Custom DBTransactionImpl2 Subclass

If you want to...

Override this method in your custom


DBTransactionImpl2 class

commit()
Perform custom code before or after the
transaction commit operation
rollback()
Perform custom code before or after the
transaction rollback operation
In order to have your custom DBTransactionImpl2 subclass get used at runtime, there are two steps you must
follow:
1.

2.

Create a custom subclass of DatabaseTransactionFactory that overrides the create method to


return an instance of your customDBTransactionImpl2 subclass like this:
packagecom.yourcompany.adfextensions;
importoracle.jbo.server.DBTransactionImpl2;
importoracle.jbo.server.DatabaseTransactionFactory;
importcom.yourcompany.adfextensions.CustomDBTransactionImpl;
publicclassCustomDatabaseTransactionFactoryextendsDatabaseTransactionFactory{
/**
*ReturnaninstanceofourcustomCustomDBTransactionImplclass
*insteadofthedefaultimplementation.
*
*@returnAninstanceofourcustomDBTransactionImpl2implementation.
*/
publicDBTransactionImpl2create(){
returnnewCustomDBTransactionImpl();
}
}
Tell the framework to use your custom transaction factory class by setting the value of
the TransactionFactory configuration property to the fully-qualified class name of your custom transaction
factory. As with other configuration properties, if not supplied in the configuration XML file, it can be provided
alternatively as a Java system parameter of the same name.
EntityImpl Class
The EntityImpl
class is the base class for entity objects, which encapsulate the data, validation rules,
and business behavior for your business domain objects.
Methods You Typically Call on EntityImpl

If you want
to...

Call this method in your EntityImpl subclass

Get the value of getAttributeName()


an attribute
Note Code-generated getter method calls getAttributeInternal() but provides compile:
time type checking.
Set the value of setAttributeName()
an attribute
Note Code-generated setter method calls setAttributeInternal() but provides compile:
time type checking.
Get the value of getAttributeInternal()
an attribute by
name
Set the value of setAttributeInternal()
an attribute by
name
Eagerly perform validate()
entity object
validation
refresh()
Refresh the
entity from the
database
populateAttributeAsChanged()
Populate the
value of an
attribute
without marking i
t as being
changed, but
sending notificati
on of its being
changed so UI's
refresh the value
on the
screen/page.
getDefinitionObject()
Access the
definition object
for an entity
getKey()
Get the Key
object for an
entity
Determine the getEntityState()
state of the entity
instance,
Not Will return one of the
irrespective of e:
constants STATUS_UNMODIFIED, STATUS_INITIALIZED,STATUS_NEW, STATUS_MODIF
whether it has
IED, STATUS_DELETED, or STATUS_DEADindicating the status of the entity instance in the
already been
current transaction.
posted in the
current
transaction (but
not yet
committed)
Determine the getPostState()
state of the entity
instance
Note This method is typically only relevant if you are programmatically using
:
thepostChanges() method to post but not yet commit entity changes to the database
and need to detect the state of an entity with regard to its posting state
getPostedAttribute()
Get the value
originally read
from the
database for a
given attribute
Eagerly lock the lock()

database row for


an entity
instance
Methods You Typically Write in Your Custom EntityImpl Subclass

If you want
to...
Perform attributespecific validation

Write a method like this in your EntityImpl subclass


publicbooleanvalidateSomething(AttrTypevalue)
Note Register the attribute validator method by adding a "MethodValidator" on correct
:
attribute in the Validation panel of the Entity Object editor. When you register the

method validation
Perform entity-level publicbooleanvalidateSomething()
validation
Note Register the entity-level validator method by adding a "MethodValidator" on the entity in
:
the Validation panel of the Entity Object editor.
Calculate the value Add your calculation code to the generated getAttributeName()method.
of a transient
attribute
Methods You Typically Override on EntityImpl

If you want to...

Override this method in your custom EntityImpl subclass...

Set calculated default attribute create()


values, including
programmatically populating the Note After calling super.create(), call the
primary key attribute value of a :
appropriate setAttrName()method(s) to set the default values for
new entity instance.
that(/those) attributes.
Modify attribute values before prepareForDML()
changes are posted to the
database
Augment/change the standard doDML()
INSERT, UPDATE, or DELETE
DML operation that the
Note Check the value of the operation flag to the
framework will perform on your :
constants DML_INSERT, DML_UPDATE, or DML_DELETE to test what DML
entity object's behalf to the
operation is being performed.
database
Perform complex, SQL-based beforeCommit()
validation after all entity
instances have been posted to
the database but before those
changes are committed.
Insure that a related, newlypostChanges()
created, parent entity gets
posted to the
Note If the parent entity is related to this child entity via a composition
database before the current
:
association, then the framework already handles this automatically. If they
child entity on which it depends
are only associated (but not composed) then you need to
override postChanges() method to force a newly-created parent entity to
post before the current, dependent child entity. See this OTN article for the
code you typically write in your overriddenpostChanges() method to
accomplish this.
NOTE:It is possible to write attribute-level validation code directly inside the
appropriate setAttributeNamemethod of your EntityImplclass, however adopting
the MethodValidator approach suggested above results in having a single place on the Validation tab
of the Entity Object editor to look in order to understand all of the validations in effect for your entity object,
so it can result in easier to understand components.

It is also possible to override the validateEntity() method to write entity-level validation code, however if
you want to maintain the benefits of the ADF bundled exception mode where the framework collects and
reports a maximal set of validation errors back to the client user interface it is recommended to adopt
the MethodValidator approach suggested in the table above. This allows the framework to automatically
collect all of your exceptions that your validation methods throw without your having to understand the bundled
exception implementation mechanism. Overriding the validateEntity() method directly shifts the
responsibility on your own code to correctly catch and bundle the exceptions like the ADF framework would have
done by default, which is non-trivial and a chore to remember and hand-code each time.
EntityDefImpl Class
The EntityDefImpl
class is a singleton, shared metadata object for all entity objects of a given type in
a single Java VM. It defines the structure of the entity instances and provides methods to create new entity
instances and find existing instances by their primary key.
Methods You Typically Call on EntityDefImpl

If you want to...

Call the EntityDefImpl method

Find an entity object of a this type by findByPrimaryKey()


its primary key
Note See this tip for getting findByPrimaryKey() to find entity
:
instances of subtype entities as well.
getDBTransaction()
Access the
currentDBTransaction object
Find any EntityDefImpl object by findDefObject() (static method)
its fully-qualified name
Retrieve the value of an entity object's getProperty(), getProperties()
custom property
setProperty()
Set the value of an entity object's
custom property
Create a new instance of an entity
createInstance()
object
Note This method has protected access, so you'll need visit
:
the Java tab of the Entity Object editor to indicate you want a
custom EntityDefImpl subclass for your entity object in question.
Then, from code you write inside this custom subclass, you can
invoke this method.
Alternatively, you can expose custom createXXX()methods with
your own expected signatures in that same
custom EntityDefImpl subclass. See the next section for details.
Iterate over the entity instances in the getAllEntityInstancesIterator()
cache of this entity type.
Access ArrayList of entity definition getExtendedDefObjects()
objects for entities that extend the
current one.
Methods You Typically Write on EntityDefImpl

If you want to...

Write a method like this in your custom EntityDefImpl class

Allow other classes to create createXXXX(Type1arg1,...,TypeNargN)


an entity instance with an
initial type-safe set of attribute Note
Internally, this would create and populate an instance of
values or setup information. :
a NameValuePairs object (which implements AttributeList) and call the
protected method createInstance(), passing thatNameValuePairs object.
Make sure the method is public if other classes need to be able to call it.
Methods You Typically Override on EntityDefImpl

If you want to...


Perform custom metadata
initialization when this singleton
metaobject is loaded.

Call the EntityDefImpl method


createDef()

Avoid using the RETURNING


isUseReturningClause()
INTO clause to support refresh-oninsert or refresh-on-update
Note Return false to disable the use of RETURNINGINTO, necessary
attributes
:
sometimes when your entity object is based on a view with INSTEAD
OF triggers that doesn't support RETURNINGINTO at the database
level.
Control whether the UPDATE
isUpdateChangedColumns()
statements issued for this entity
update only changed columns, or Note:
Defaults to true.
all columns
Find any EntityDefImpl object by its findDefObject()
fully-qualified name
Note:
Static method.
Set the value of an entity object's setProperty()
custom property
Allow other classes to create a new createInstance()
instance an entity object without
doing so implicitly via a view object. Note
If you don't write a custom create method as noted in the previous
:
section, you'll need to override this method and widen the visibility
from protected to public to allow other classes to construct an
entity instance.
ViewObjectImpl Class
The ViewObjectImpl

class the base class for view objects.

Methods You Typically Call on ViewObjectImpl

If you want to...

Call this ViewObjectImpl method

Perform any of the common view See the ViewObject Interface, RowSet Interface, and RowSetIterator
object, rowset, or rowset iterator
Interface sections above.
operations from inside your class,
which can also be done from the
client
Set an additional runtime WHERE setWhereClause()
clause on the default rowset
setWhereClauseParam()
Set bind variable values on the
default rowset
getFilteredRows()
Retrieved a subset of rows in a
view object's row set based on
evaluating an in-memory filter
expression.
Retrieved a subset of rows in the getFilteredRowsInRange()
current range of a view object's row
set based on evaluating an inmemory filter expression.
Set the number of rows that will be setFetchSize()
fetched from the database per
round-trip for this view object.
Note The default fetch size is a single row at a time. This is definitely not
:
optimal if your view object intends to retrieve many rows, so you should
either set the fetch size higher at design time on the Tuning tab of the
View Object editor, or set it at runtime using this API.
Methods You Typically Write in Your Custom ViewObjectImpl Subclass

If you want to...

Write a method like this in your ViewObjectImpl


subclass

Provide clients with type-safe methods to someMethodName(Type1arg1,...,TypeNargN)


set bind variable values without exposing
positional details of the bind variables
Note Internally, this method would call the setWhereClauseParam()
themselves
:
API to set the correct bind variables with the values provided in

the type-safe method arguments.


JDeveloper 10g can generate you a custom YourViewObjectNameinterface containing view object custom
methods that you've chosen to expose to the client. You can accomplish this by visiting the Client Interface tab
of the View Object editor, and shuttling the methods you'd like to appear in your client interface into
the Selected list.
Methods You Typically Override in Your Custom ViewObjectImpl Subclass

If you want to...


Initialize custom view object class
members (not row attributes!) when the
view object instance is created for the
first time.

Override this ViewObjectImpl method


create()
Note This method is useful to perform setup logic that is applicable to
:
every instance of a view object that will ever get created, in the
context of any application module.
If instead of generic view object setup logic, you need to perform
logic specific to a given view object instance in an application
module, then override theprepareSession() method of your
application module'sApplicationModuleImpl subclass and
perform the logic there after callingfindViewObject() to find
the view object instance whose properties you want to set.
passivateState()

Write custom view object instance state


to the state management XML snapshot
activateState()
Read and restore custom view object
instance state from the state
management XML snapshot
executeQueryForCollection()
Customize the behavior of view object
query execution, independent of whether
the query was executed explicitly by
calling executeQuery() or implicitly, for
example, by navigating to
the first() row when the query hadn't
yet been executed.
getViewCriteriaClause()
Change/augment the way that
the ViewCriteriacollection
of ViewCriteriaRows is converted into
a query-by-example WHERE clause.
ViewRowImpl Class
The ViewRowImpl
class the base class for view row objects.
Methods You Typically Call on ViewRowImpl

Write a method like this in your custom


ViewRowImpl class

If you want to...


Perform any of the common view row
operations from inside your class, which can
also be done from the client
Get the value of an attribute
Set the value of an attribute
Access the underlying entity instance to which
this view row is delegating attribute storage.

See the Row Interface section above.


getAttrName()
setAttrName()
getEntityUsageAliasName()
Note You can change the name of the entity usage alias name on
:
theEntity Objects tab of the View Object Editor

Methods You Typically Write on ViewRowImpl

If you want to...


Calculate the value of a view object
level transient attribute

Write a method like this in your custom ViewRowImpl


class
getAttrName()
Note JDeveloper generates the skeleton of the method for you, but you

:
Perform custom processing of the
setting of a view row attribute

need to write the custom calculation logic inside the method body.

setAttrName()
Note JDeveloper generates the skeleton of the method for you, but you
:
need to write the custom logic inside the method body if required.

isAttributeUpdateable()
Determine the updateability of an
attribute in a conditional way.
Custom methods that expose logical
doSomething()
operations on the current row, optionally
callable by clients
Note Often these view-row level custom methods simply turn around and
:
delegate to a method call on the underlying entity object related to
the current row.
JDeveloper 10g can generate you a custom YourViewObjectNameRowinterface containing view row custom
methods that you've chosen to expose to the client. You can accomplish this by visiting the Client Row
Interface tab of the View Object editor, and shuttling the methods you'd like to appear in your client interface into
the Selected list.
Methods You Typically Override in Your Custom ViewRowImpl Subclass

If you want to...

Write a method like this in your custom


ViewRowImpl class

Determine the updateability of an attribute in a isAttributeUpdateable()


conditional way.
Setting Up Your Own Layer of Framework Base Classes
Before you begin to develop application specific business components, we recommend creating yourself a layer
of classes that extend all of the ADF Business Components framework base implementation classes described in
this paper. An example of a customized framework base class for application module components might look like
this:

packagecom.yourcompany.adfextensions;
importoracle.jbo.server.ApplicationModuleImpl;
publicclassCustomApplicationModuleImplextendsApplicationModuleImpl{
/*
*Wemightnotyethaveanycustomcodetoputhereyet,but
*thefirsttimeweneedtoaddagenericfeaturethatallof
*ourcompany'sapplicationmodulesneed,wewillbeveryhappy
*thatwethoughtaheadtoleaveourselvesaconvenientplace
*inourclasshierarchytoadditsothatalloftheapplication
*moduleswehavecreatedwillinstantlybenefitbythatnewfeature,
*behaviorchange,orevenperhaps,bugworkaround.
*/
}
A common set of customized framework base classes in a package name of your own choosing
like com.yourcompany.adfextensions, each importing the oracle.jbo.server.* package, would
consist of the following classes.
publicclassCustomEntityImplextendsEntityImpl
publicclassCustomEntityDefImplextendsEntityDefImpl
publicclassCustomViewObjectImplextendsViewObjectImpl
publicclassCustomViewRowImplextendsViewRowImpl
publicclassCustomApplicationModuleImplextendsApplicationModuleImpl
publicclassCustomDBTransactionImplextendsDBTransactionImpl2
publicclassCustomDatabaseTransactionFactoryextends
DatabaseTransactionFactory
For completeness, you may also want to create customized framework classes for the following classes as well,
but overriding anything in these classes would be a fairly rare requirement.
publicclassCustomViewDefImplextendsViewDefImpl
publicclassCustomEntityCacheextendsEntityCache
publicclassCustomApplicationModuleDefImplextendsApplicationModuleDefImpl

Conclusion
Hopefully this short list of methods will assist you in getting started with Oracle ADF Business Components to
focus your attention on these most frequently used methods instead of feeling bewildered about the many other
methods that could be overridden but which aren't often done in practice.
If you have already been using ADF Business Components for some time and notice some methods you use
frequently that didn't make my list, please send me an email to let me know what I should add to the list. Include
in your email a brief description of how you're using the method, or what functionality you often providing in the
overridden version of the method. Thanks!
Revision History
Date
Comments
18-Nov- Created
2004
19-Nov- Updated diagram to include StructureDef, AttributeDef, and AttributeHints, and added some text on
2004
the generated client proxy classes.
20-Nov- Added a comment about passing null to the createRowSetIterator method
2004
30-Nov- Added getPostedAttribute() and getEntityState()
2004
1-DecClarified getPostState() and getEntityState()
2004
1-JanAdded some use case information for prepareSession()
2005
14-Mar- Clarified when to use VOImpl.create() vs AMImpl.prepareSession()
2005
15-Mar- Clarified when to prepareForDML() vs postChanges()
2005
14-Jun- Clarified that EntityImpl.create() is used for programmatically populating primary key attributes as well
2005
19-Jan- Updated javadoc links
2006
false ,,,,,,,,,,,,,,,

Das könnte Ihnen auch gefallen