E Most Commonly Used ADF Business Components Methods

This appendix highlights the most commonly used methods in the interfaces and classes of the ADF Business Components layer of Oracle Application Development Framework (Oracle ADF).

This appendix contains the following sections:

E.1 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.

This section provides a summary of the most frequently called, written, and overridden methods for the key ADF Business Components interfaces.

Note:

The corresponding implementation classes for these oracle.jbo.* interfaces are intentionally designed to not be directly accessed by client code. Section E.2, "Most Commonly Used Methods in the Business Service Tier" shows that the implementation classes reside in the oracle.jbo.server.* package and generally have the suffix Impl in their name to help remind you not to use them in your client-layer code.

E.1.1 ApplicationModule Interface

An application module is a business service component that acts as a transactional container for other ADF components and coordinates with them to implement a number of Java EE design patterns important to business application developers. These design pattern implementations enable your client code to work easily with updatable 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. Table E-1 describes the operations that you can perform on an application module using the ApplicationModule interface.

Note:

For the complete list of design patterns that ADF Business Components implements, see Appendix F, "ADF Business Components Java EE Design Pattern Catalog."

Table E-1 ApplicationModule Interface

If you want to... Call this ApplicationModule interface method

Access an existing view object instance using the assigned instance name (for example, MyVOInstanceName)

findViewObject()

Create a new view object instance from an existing definition

createViewObject()

Create a new view object instance from a SQL Statement

createViewObjectFromQueryStmt()

Notes:

This incurs runtime overhead to describe the "shape" of the dynamic query's SELECT list. Use this method 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 the steps to create (both read-only and updatable) dynamic view objects without the runtime-describe overhead, as described in Section 39.9, "Creating a View Object with Multiple Updatable Entities." 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 APIs.

Access a nested application module instance by name

findApplicationModule()

Create a new nested application module instance from an existing definition

createApplicationModule()

Find a view object instance in a nested application module using a dot-notated name (for example, MyNestedAMInstanceName.OneOfItsVONames)

findViewObject()

Notes:

You can use this method to find an instance of a view object belonging to a nested application module in a single method call. This way you do not need to first call findApplicationModule() to find the nested application module, before calling findViewObject() on that nested application module.

Access the current transaction object

getTransaction()


In addition to generic application module access, Oracle JDeveloper can generate a custom YourApplicationModuleName interface containing service-level custom methods that you've chosen to expose to the client. You use the Client Interface page of the Edit Application Module dialog to select the methods that you want to appear in your client interface.

E.1.2 Transaction Interface

The Transaction interface exposes methods allowing the client to manage pending changes in the current transaction. Table E-2 describes the operations that you can perform on the transaction using the Transaction interface.

Table E-2 Transaction Interface

If you want to... Call this Transaction interface method

Commit pending changes

commit()

Roll back pending changes

rollback()

Execute a one-time database command or block of PL/SQL

executeCommand()

Notes:

Do not use this command with methods that require retrieving OUT parameters and that will be executed more than once, or that could benefit from using bind variables. Instead, expose a custom method on your application module.

Validate all pending invalid changes in the transaction

validate()

Change the default locking mode

setLockingMode()

Notes:

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 the locking mode, it will default to optimistic. For Fusion web applications, use optimistic or optupdate modes.

Decide whether to use bundled exception reporting mode or not

setBundledExceptionMode()

Notes:

ADF Controller layer support sets this parameter to true automatically for Fusion web applications.

Decide whether entity caches will be cleared upon a successful commit of the transaction

setClearCacheOnCommit()

Notes:

Default is false.

Decide whether entity caches will be cleared upon a rollback of the transaction

setClearCacheOnRollback()

Notes:

Default is true.

Clear the entity cache for a specific entity object

clearEntityCache()


E.1.3 ViewObject Interface

A view object is a component that encapsulates a database query and simplifies working with the row set of results it produces. You use view objects to project, filter, join, or sort business data using SQL from one or more tables to cast the data into exactly the format that the user should see on the page or panel. You can create "master-detail" hierarchies of any depth or complexity by connecting view objects together using view links. View objects can produce read-only query results, or when associated with one or more entity objects at design time, can be fully updatable. Updatable view objects can support insertion, modification, and deletion of rows in the result collection, with automatic delegation to the correct business domain objects.

Every view object contains a "default row set" for simplifying the 90 percent of use cases where you work with a single row set of results for the view object's query. A view object 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 view object as well.

Every view object implements the StructureDef interface to provide information about the number and types of attributes in a row of its row sets. So you can call StructureDef methods directly on any view object.

Table E-3 describes the operations that you can perform on a view object using the ViewObject interface

Table E-3 ViewObject Interface

If you want to... Call this ViewObject interface method

Set an additional runtime WHERE clause on the row set

setWhereClause()

Notes:

This WHERE clause augments any WHERE clause specified at design time in the base view object. It does not replace it.

Set a dynamic ORDER BY clause

setOrderByClause()

Create a Query-by-Example criteria collection

createViewCriteria()

Notes:

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 applyViewCriteria() method.

Apply a Query-by-Example criteria collection

applyViewCriteria()

Set a query optimizer hint

setQueryOptimizerHint()

Access the attribute definitions for the key attributes in the view object

getKeyAttributeDefs()

Add a dynamic attribute to rows in this view object's row sets

addDynamicAttribute()

Clear all row sets produced by a view object

clearCache()

Remove a view object instance and its resources

remove()

Set an upper limit on the number of rows that the view object will attempt to fetch from the database

setMaxFetchSize()

Notes:

Default is -1, which means to impose no limit on how many rows would be retrieved from the database if you iterated through them all. By default, as you iterate through them, they are fetched lazily.


In addition to generic ViewObject access, JDeveloper can generate you a custom YourViewObjectName interface containing view object-level custom methods that you've chosen to expose to the client. You use the Client Interface page of the Edit View Object dialog to select the methods that you want to appear in your client interface.

E.1.4 RowSet Interface

A row set is an object that contains a set of rows, typically produced by executing a view object's query.

Every RowSet aggregates a "default row set iterator" for simplifying the 90 percent of use cases where you need only a single iterator over the row set. A RowSet object 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 object (or view object, since it implements RowSet, as well for its default RowSet).

Table E-4 describes the operations that you can perform on a row set using the RowSet interface.

Table E-4 RowSet Interface

If you want to... Call this RowSet interface method

Set a WHERE clause bind variable value

setWhereClauseParam()

Notes:

Bind variable ordinal positions are zero-based.

Avoid view object row caching if data is being read only once

setForwardOnly()

Force a row set's query to be (re)executed

executeQuery()

Estimate the number of rows in a view object's query result

getEstimatedRowCount()

Produce an XML document for rows in a view object row set

writeXML()

Process all rows from an incoming XML document

readXML()

Set whether a row set will automatically see new rows based on the same entity object created through other row sets

setAssociationConsistent()

Create a secondary iterator to use for programmatic iteration

createRowSetIterator()

Notes:

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.


E.1.5 RowSetIterator Interface

A row set iterator is an iterator over the rows in a row set. By default it allows you to iterate both forward and backward through the rows. Table E-5 describes the operations that you can perform on a row set using the RowSetIterator interface.

Table E-5 RowSetIterator Interface

If you want to... Call this RowSetIterator interface method

Get the first row of the iterator's row set

first()

Test whether there are more rows to iterate

hasNext()

Get the next row of an iterator's row set

next()

Find a row in this iterator's row set with a given key value

findByKey()

Notes:

It's important that the Key object that you pass to findByKey be created using the exact same data types as the attributes that comprise the key of the rows in the view object you're working with.

Create a new row to populate for insertion

createRow()

Notes:

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 overridden create() method of the underlying entity object(s).

Create a view row with an initial set of foreign key and/or discriminator attribute values

createAndInitRow()

Notes:

You use this method when working with view objects that can return one of a "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 row set

insertRow()

Notes:

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.

Get the last row of the iterator's row set

last()

Get the previous row of the iterator's row set

previous()

Reset the current row pointer to the slot before the first row

reset()

Close an iterator when done iterating

closeRowSetIterator()

Set a given row to be the current row

setCurrentRow()

Remove the current row

removeCurrentRow()

Remove the current row to later insert it at a different location in the same iterator

removeCurrentRowAndRetain()

Remove the current row from the current collection but do not remove it from the transaction.

removeCurrentRowFromCollection()

Set/change the number of rows in the range (a "page" of rows the user can see)

setRangeSize()

Scroll to view the nth page of rows (1-based)

scrollToRangePage()

Scroll to view the range of rows starting with row number n

scrollRangeTo()

Set row number n in the range to be the current row

setCurrentRowAtRangeIndex()

Get all rows in the range as a row array

getAllRowsInRange()


E.1.6 Row Interface

A row is generic value object. It contains attributes appropriate in name and Java type for the view object that it is related to. Table E-6 describes the operations that you can perform on a view object row using the Row interface.

Table E-6 Row Interface

If you want to... Call this Row interface method

Get the value of an attribute by name

getAttribute()

Set the value of an attribute by name

setAttribute()

Produce an XML document for a single row

writeXML()

Eagerly validate a row

validate()

Read row attribute values from XML

readXML()

Remove the row

remove()

Flag a newly created row as temporary (until updated again)

setNewRowState(Row.STATUS_INITIALIZED)

Retrieve the attribute structure definition information for a row

getStructureDef()

Get the Key object for a row

getKey()


In addition to generic Row access, JDeveloper can generate a custom YourViewObjectNameRow interface 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 use the Client Row Interface page of the Edit View Object dialog to select the methods that you want to appear in your client interface.

E.1.7 StructureDef Interface

The StructureDef interface provides access to runtime metadata about the structure of a Row object.

In addition, for convenience every view object implements the StructureDef interface as well, providing access to metadata about the attributes in the resulting view rows that its query will produce.

Table E-7 describes the operations that you can perform on a view object row using the StructureDef interface.

Table E-7 StructureDef Interface

If you want to... Call this StructureDef interface method

Access attribute definitions for all attributes in the view object row

getAttributeDefs()

Find an attribute definition by name

findAttributeDef()

Get attribute definition by index

getAttributeDef()

Get number of attributes in a row

getAttributeCount()


E.1.8 AttributeDef Interface

The AttributeDef interface 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 attribute-specific 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. Table E-8 describes the operations that you can perform on an attribute using the AttributeDef interface.

Table E-8 AttributeDef Interface

If you want to... Call this AttributeDef interface method

Get the Java type of the attribute

getJavaType()

Get the SQL type of the attribute

getSQLType()

Notes:

The int value corresponds to constants in the JDBC class java.sql.Types.

Determine the kind of attribute

getAttributeKind()

Notes:

A simple attribute is one that returns one of the constants ATTR_PERSISTENT, ATTR_SQL_DERIVED, ATTR_TRANSIENT, ATTR_DYNAMIC, ATTR_ENTITY_DERIVED. If the attribute is a 1-to-1 or many-to-1 association/viewlink accessor, it returns ATTR_ASSOCIATED_ROW. If the attribute is a 1-to-many or many-to-many association/viewlink accessor, it returns ATTR_ASSOCIATED_ROWITERATOR

Get the Java type of elements contained in an Array-valued attribute

getElemJavaType()

Get the SQL type of elements contained in an Array-valued attribute

getElemSQLType()

Get the name of the attribute

getName()

Get the index position of the attribute

getIndex()

Get the precision of a numeric attribute or the maximum length of a string attribute

getPrecision()

Get the scale of a numeric attribute

getScale()

Get the underlying column name corresponding to the attribute

getColumnNameForQuery()

Get attribute-specific custom property values

getProperty(), getProperties()

Get the UI AttributeHints object for the attribute

getUIHelper()

Test whether the attribute is mandatory

isMandatory()

Test whether the attribute is queriable

isQueriable()

Test whether the attribute is part of the primary key for the row

isPrimaryKey()


E.1.9 AttributeHints Interface

The AttributeHints interface exposes UI hint information that you can use to render an appropriate user interface display for the attribute and its value. Table E-9 describes the operations that you can perform on an attribute using the AttributeHints interface.

Table E-9 AttributeHints Interface

If you want to... Call this AttributeHints interface method

Get the UI label for the attribute

getLabel()

Get the tooltip for the attribute

getTooltip()

Get the formatted value of the attribute, using any format mask supplied

getFormattedAttribute()

Get the display hint for the attribute

getDisplayHint()

Notes:

The display hint will have a string value of either Display or Hide.

Get the preferred control type for the attribute

getControlType()

Parse a formatted string value using any format mask supplied for the attribute

parseFormattedAttribute()


E.2 Most Commonly Used Methods in the Business Service Tier

The implementation classes corresponding to the oracle.jbo.* interfaces, as described in Section E.1, "Most Commonly Used Methods in the Client Tier," are intentionally designed to not be directly accessed by client code. They reside in a different package named oracle.jbo.server.* and have the Impl suffix in their name to help remind you not to use 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, 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 public or protected methods for the base framework implementation classes and write custom code in your component subclass before or after calling super.methodName() to augment or change the default functionality.

This section provides a summary of the most frequently called, written, and overridden methods for the key ADF Business Components classes.

E.2.1 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 page in its component overview editor in the JDeveloper IDE. By selecting or deselecting the different Java classes, you control which ones will be created for your component. If none of the classes is specified, 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 will create a custom subclass of the framework base class in which you can add your code.

Note:

You can set up global IDE preferences for the Java classes to be generated by default for each ADF business component type by choosing 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 prevents errors surfacing at runtime in response to an attribute having been set to an incorrect kind of value.

E.2.2 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 updatable collections of value objects that are automatically "wired" to business domain objects. The business domain objects are implemented as ADF entity objects.

E.2.2.1 Methods You Typically Call on ApplicationModuleImpl

Table E-10 describes the operations that you can perform on an application module using the ApplicationModuleImpl class.

Table E-10 Methods You Typically Call on ApplicationModuleImpl

If you want to... Call this method of the ApplicationModuleImpl class

Perform any of the common application module operations from inside your class, which can also be done from the client

For a list of these methods, see Section E.1.1, "ApplicationModule Interface."

Access a view object instance that you added to the application module's data model at design time

getViewObjectInstanceName()

Notes:

JDeveloper 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.

Access the current DBTransaction object

getDBTransaction()

Access a nested application module instance that you added to the application module at design time

getAppModuleInstanceName()

Notes:

JDeveloper 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.


E.2.2.2 Methods You Typically Write in Your Custom ApplicationModuleImpl Subclass

Table E-11 describes the operations that you can perform on an application module using your custom ApplicationModuleImpl class.

Table E-11 Methods You Typically Write in Your Custom ApplicationModuleImpl Subclass

If you want to... Write a method like this in your custom ApplicationModuleImpl class

Invoke a database stored procedure

someCustomMethod()

Notes:

Use the appropriate method on the DBTransaction interface to create a JDBC PreparedStatement. If the stored procedure has OUT parameters, then create a CallableStatement instead.

For sample code that demonstrates encapsulating a call to a PL/SQL stored procedure inside your application module, see Section 37.5, "Invoking Stored Procedures and Functions."

Expose custom business service methods on your application module

someCustomMethod()

Notes:

Select the method name on the Client Interface page of the Edit Application Module dialog to expose it for client access if required.


JDeveloper can generate a custom YourApplicationModuleName interface containing service-level custom methods that you've chosen to expose to the client. You can use the Client Interface page of the Edit Application Module dialog to select the methods that you want to appear in your client interface.

E.2.2.3 Methods You Typically Override in Your Custom ApplicationModuleImpl Subclass

Table E-12 describes the operations that you can override on an application module using your custom ApplicationModuleImpl class.

Table E-12 Methods You Typically Override in Your Custom ApplicationModuleImpl Subclass

If you want to... Override this method in your custom ApplicationModuleImpl class

Perform custom setup code the first time an application module is created and each subsequent time it gets used by a different client session.

prepareSession()

Notes:

This is the method you'd use to set up per-client context info for the current user in order to use Oracle's Virtual Private Database (VPD) features. It can also be used to set other kinds of PL/SQL package global variables, whose values might be client-specific, on which other stored procedures might rely.

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 the view object setup code being instance-specific, you want it 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 code after the application module's transaction is associated with a database connection from the connection pool

afterConnect()

Notes:

Can be a useful place to write a line of code that uses getDBTransaction().executeCommand() to perform an ALTER SESSION SET SQL TRACE TRUE to enable database SQL trace logging for the current application connection. These logs can then be processed with the TKPROF utility to study the SQL statements being performed and the query optimizer plans that are getting used.

For details about the TKPROF utility, see the "Understanding SQL Trace and TKPROF" section in the Oracle Database Performance Tuning Guide.

Perform custom setup code before the application module's transaction releases its database connection back to the database connection pool

beforeDisconnect()

Notes:

If you have set jbo.doconnectionpooling to true, then the connection is released to the database connection pool each time the application module is returned to the application module pool.

Write custom application module state to the state management XML snapshot

passivateState()

Read and restore custom application module state from the state management XML snapshot

activateState()


E.2.3 DBTransactionImpl2 Class

The DBTransactionImpl2 class — which extends the base DBTransactionImpl class, and is constructed by the DatabaseTransactionFactory class — is the base class that implements the DBTransaction interface, representing the unit of pending work in the current transaction.

E.2.3.1 Methods You Typically Call on DBTransaction

Table E-13 describes the operations that you can perform on a transaction using the DBTransaction class.

Table E-13 Methods You Typically Call on DBTransaction

If you want to... Call this method on the DBTransaction class

Commit the transaction

commit()

Roll back the transaction

rollback()

Eagerly validate any pending invalid changes in the transaction

validate()

Create a JDBC PreparedStatement using the transaction's Connection object

createPreparedStatement()

Create a JDBC CallableStatement using the transaction's Connection object

createCallableStatement()

Create a JDBC Statement using the transaction's Connection object

createStatement()

Add a warning to the transaction's warning list

addWarning()


E.2.3.2 Methods You Typically Override in Your Custom DBTransactionImpl2 Subclass

Table E-14 describes the operations that you can perform on a transaction using your custom DBTransactionImpl2 subclass.

Table E-14 Methods You Typically Override in Your Custom DBTransactionImpl2 Subclass

If you want to... Override this method in your custom DBTransactionImpl2 class

Perform custom code before or after the transaction commit operation

commit()

Perform custom code before or after the transaction rollback operation

rollback()


In order for your custom DBTransactionImpl2 subclass to be used at runtime, there are you must follow these steps:

  1. Create a custom subclass of DatabaseTransactionFactory that overrides the create method to return an instance of your custom DBTransactionImpl2 subclass like this:

    package com.yourcompany.adfextensions;
    import oracle.jbo.server.DBTransactionImpl2;
    import oracle.jbo.server.DatabaseTransactionFactory;
    import com.yourcompany.adfextensions.CustomDBTransactionImpl;
    public class CustomDatabaseTransactionFactory
           extends DatabaseTransactionFactory {
      /**
       * Return an instance of our custom CustomDBTransactionImpl class
       * instead of the default implementation.
       *
       * @return An instance of our custom DBTransactionImpl2 implementation.
       */
      public DBTransactionImpl2 create() {
        return new CustomDBTransactionImpl();
      }
    }
    
  2. 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.

E.2.4 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.

E.2.4.1 Methods You Typically Call on EntityImpl

Table E-15 describes the operations that you can perform on an entity object using the EntityImpl class.

Table E-15 Methods You Typically Call on EntityImpl

If you want to... Call this method in the EntityImpl class

Get the value of an attribute

getAttributeName()

Notes:

This code-generated getter method calls getAttributeInternal(), but provides compile-time type checking.

Set the value of an attribute

setAttributeName()

Notes:

This code-generated setter method calls setAttributeInternal(), but provides compile-time type checking.

Get the value of an attribute by name

getAttributeInternal()

Set the value of an attribute by name

setAttributeInternal()

Eagerly perform entity object validation

validate()

Refresh the entity from the database

refresh()

Populate the value of an attribute without marking it as being changed, but sending notification of its being changed so that the UI refreshes the value on the screen/page

populateAttributeAsChanged()

Access the Definition object for an entity

getDefinitionObject()

Get the Key object for an entity

getKey()

Determine the state of the entity instance, irrespective of whether it has already been posted (but not yet committed) in the current transaction

getEntityState()

Notes:

This method will return one of the constants STATUS_UNMODIFIED, STATUS_INITIALIZED, STATUS_NEW, STATUS_MODIFIED, STATUS_DELETED, or STATUS_DEAD, indicating the status of the entity instance in the current transaction.

Determine the state of the entity instance

getPostState()

Notes:

This method is typically relevant only if you are programmatically using the postChanges() 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.

Get the value originally read from the database for a given attribute

getPostedAttribute()

Eagerly lock the database row for an entity instance

lock()


E.2.4.2 Methods You Typically Write in Your Custom EntityImpl Subclass

Table E-16 describes the operations that you can perform on an entity object using your custom EntityImpl subclass.

Table E-16 Methods You Typically Write in Your Custom EntityImpl Subclass

If you want to... Write a method like this in your custom EntityImpl subclass

Perform attribute-specific validation

public boolean validateSomething(AttrTypevalue)

Notes:

Register the attribute validator method by adding a MethodValidator rule on the correct attribute in the Validation page of the Edit Entity Object dialog.

Perform entity-level validation

public boolean validateSomething()

Notes:

Register the entity-level validator method by adding a MethodValidator rule on the entity in the Validation panel of the Edit Entity Object dialog.

Calculate the value of a transient attribute

Add your calculation code to the generated getAttributeName() method.


E.2.4.3 Methods You Typically Override in Your Custom EntityImpl Subclass

Table E-17 describes the operations that you can override on an entity object using your custom EntityImpl subclass.

Table E-17 Methods You Typically Override in Your Custom EntityImpl Subclass

If you want to... Override this method in your EntityImpl subclass

Set calculated default attribute values, including programmatically populating the primary key attribute value of a new entity instance

create()

Notes:

After calling super.create(), call the appropriate setAttrName() method(s) to set the default values for the attributes.

Modify attribute values before changes are posted to the database

prepareForDML()

Augment or change the standard INSERT, UPDATE, or DELETE DML operation that the framework will perform on your entity object's behalf to the database

doDML()

Notes:

This method checks the value of the operation flag to the constants DML_INSERT, DML_UPDATE, or DML_DELETE to test what DML operation is being performed.

Perform complex, SQL-based validation after all entity instances have been posted to the database but before those changes are committed

beforeCommit()

Insure that a related, newly-created, parent entity gets posted to the database before the current child entity on which it depends

postChanges()

Notes:

If the parent entity is related to this child entity via a composition association, then the framework already handles posting the changes automatically. If they are only associated (but not composed), then you need to override postChanges() to force a newly created parent entity to post before the current, dependent child entity. For an example of the code you typically write in your overridden postChanges() method to accomplish this, see Section 38.8.3, "Overriding postChanges() to Control Post Order."


Note:

It is possible to write attribute-level validation code directly inside the appropriate setAttributeName method of your EntityImpl class; however, adopting the MethodValidator approach suggested in Table E-16 conveniently places all the validations in effect on the Validation Rules page of the overview editor for the attributes of the entity object.

WARNING:

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 — use the MethodValidator approach suggested in Table E-16. 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 onto your own code to correctly catch and bundle the exceptions that Oracle ADF would have caught by default, which is non-trivial and a chore to remember and hand-code each time.

E.2.5 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.

E.2.5.1 Methods You Typically Call on EntityDefImpl

Table E-18 describes the operations that you can perform on an entity object using the EntityDefImpl class.

Table E-18 Methods You Typically Call on EntityDefImpl

If you want to... Call this method in the EntityDefImpl class

Find an entity object of a given type by its primary key

findByPrimaryKey()

Notes:

For a tip about getting findByPrimaryKey() to find entity instances of subtype entities as well, see Section 38.7.4.2, "Finding Subtype Entities by Primary Key."

Access the current DBTransaction object

getDBTransaction()

Find any EntityDefImpl object by its fully qualified name

findDefObject() (static method)

Retrieve the value of an entity object's custom property

getProperty(), getProperties()

Set the value of an entity object's custom property

setProperty()

Create a new instance of an entity object

createInstance2()

Notes:

Alternatively, you can expose custom createXXX() methods with your own expected signatures in that same custom EntityDefImpl subclass. See Section E.2.5.2, "Methods You Typically Write in Your Custom EntityDefImpl Class" for details.

Iterate over the entity instances in the cache of this entity type

getAllEntityInstancesIterator()

Access an array list of entity definition objects for entities that extend the current one.

getExtendedDefObjects()


E.2.5.2 Methods You Typically Write in Your Custom EntityDefImpl Class

Table E-19 describes the operations that you can perform on an entity object using your custom EntityDefImpl class.

Table E-19 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 an entity instance with an initial type-safe set of attribute values or setup information

createXXXX(Type1arg1,..., TypeNargN)

Notes:

Internally, using this method would create and populate an instance of a NameValuePairs object (which implements AttributeList) and call the protected method createInstance(), passing that NameValuePairs object. Make sure that the method is public if other classes need to be able to call it.


E.2.5.3 Methods You Typically Override in Your Custom EntityDefImpl

Table E-20 describes the operations that you can perform on an entity object using the EntityDefImpl class.

Table E-20 Methods You Typically Override on EntityDefImpl

If you want to... Override this method in your custom EntityDefImpl class

Perform custom metadata initialization when this singleton metaobject is loaded

createDef()

Avoid using the RETURNING INTO clause to support refresh-on-insert or refresh-on-update attributes

isUseReturningClause()

Notes:

Set this method to return false to disable the use of RETURNING INTO, necessary sometimes when your entity object is based on a view with INSTEAD OF triggers that don't support RETURNING INTO at the database level.

Control whether the UPDATE statements issued for this entity update only changed columns or for all columns

isUpdateChangedColumns()

Notes:

Defaults to true.

Find any EntityDefImpl object by its fully qualified name

findDefObject()

Notes:

Static method.

Set the value of an entity object's custom property

setProperty()

Allow other classes to create a new instance of an entity object without doing so implicitly via a view object

createInstance()

Notes:

If you don't write a custom create method as noted in Section E.2.5.2, "Methods You Typically Write in Your Custom EntityDefImpl Class", you'll need to override this method and widen the visibility from protected to public to allow other classes to construct an entity instance.


E.2.6 ViewObjectImpl Class

The ViewObjectImpl class is the base class for view objects.

E.2.6.1 Methods You Typically Call on ViewObjectImpl

Table E-21 describes the operations that you can perform on a view object using the ViewObjectImpl class.

Table E-21 Methods You Typically Call on ViewObjectImpl

If you want to... Call this method in the ViewObjectImpl class

Perform any of the common view object, row set, or row set iterator operations from inside your class, which can also be done from the client

For more information about operations at the view object, row set, or row set iterator-level, see Section E.1.3, "ViewObject Interface," Section E.1.4, "RowSet Interface," and Section E.1.5, "RowSetIterator Interface."

Set an additional runtime WHERE clause on the default row set

setWhereClause()

Define a named bind parameter

defineNamedWhereClauseParam()

Remove a named bind parameter

removeNamedWhereClauseParam()

Set bind variable values on the default row set by name

setNamedWhereClauseParam()

Notes:

Only works when you have formally defined named bind variables on your view object.

Set bind variable values on the default row set

setWhereClauseParam()

Notes:

Use this method for view objects with binding style of "Oracle Positional" or "JDBC Positional" when you have not formally defined named bind variables.

Retrieve a subset of rows in a view object's row set based on evaluating an in-memory filter expression

getFilteredRows()

Retrieve a subset of rows in the current range of a view object's row set based on evaluating an in-memory filter expression

getFilteredRowsInRange()

Set the number of rows that will be fetched from the database per roundtrip for this view object

setFetchSize()

Notes:

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 page of the Edit View Object dialog, or set it at runtime using this method.

Access a cached query collection without reexecuting the query (useful for view instances of a shared application module)

refreshCollection()

Notes:

When you cache lookup data in a shared application module, you should not reexecute the lookup view object query since reexecuting forces a new query collection and prevents the cache from being used. Instead of using executeQuery(), use this pattern to reuse the cached query collection:

if (!lookupVO.isExecuted()) {
  ((ViewObjectImpl)lookupVO).
    refreshCollection(null, true, true);
 }

E.2.6.2 Methods You Typically Write in Your Custom ViewObjectImpl Subclass

Table E-22 describes the operations that you can perform on a view object using your custom ViewObjectImpl subclass.

Table E-22 Methods You Typically Write in Your Custom ViewObjectImpl Subclass

If you want to... Write a method like this in your custom ViewObjectImpl subclass

Provide clients with type-safe methods to set bind variable values without exposing positional details of the bind variables themselves

someMethodName(Type1arg1,..., TypeNargN)

Notes:

Internally, this method would call the setWhereClauseParam() method to set the correct bind variables with the values provided in the type-safe method arguments.


JDeveloper can generate a custom YourViewObjectName interface containing view object custom methods that you've chosen to expose to the client. You can use the Client Interface page of the Edit View Object to select the methods that you want to appear in your client interface.

E.2.6.3 Methods You Typically Override in Your Custom ViewObjectImpl Subclass

Table E-23 describes the operations that you can perform on a view object using your custom ViewObjectImpl subclass.

Table E-23 Methods You Typically Override in Your Custom ViewObjectImpl Subclass

If you want to... Override this method in your custom ViewObjectImpl subclass

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

create()

Notes:

This method is useful to perform set up 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 the prepareSession() method of your application module's ApplicationModuleImpl subclass and perform the logic there after calling findViewObject() to find the view object instance whose properties you want to set.

Write custom view object instance state to the state management XML snapshot

passivateState()

Read and restore custom view object instance state from the state management XML snapshot

activateState()

Customize the execution of the view object query to utilize an alternative data source

executeQueryForCollection()

Notes:

By default view objects read their data from the database and automate the task of working with the JDBC layer to process the database result sets. However, by overriding appropriate methods in its custom Java class, you can create a view object that programmatically retrieves data from alterative data sources, as described in Section 39.8, "Using Programmatic View Objects for Alternative Data Sources."

Customize the programmatic view object to utilize an alternative data source and determine whether the query collection has more rows to fetch from the query execution

hasNextForCollection()

Customize the programmatic view object to utilize an alternative data source and populate each row of the retrieved data

createRowFromResultSet()

Customize the programmatic view object to utilize an alternative data source and return a count of the number of rows that will be retrieved

getQueryHitCount()

Customize the programmatic view object to utilize an alternative data source and release any resources that may be associated wiht a row set that is being closed

releaseUserDataForCollection()

Change or augment the way that the ViewCriteria collection of ViewCriteriaRows is converted into a Query-by-Example WHERE clause

getViewCriteriaClause()


E.2.7 ViewRowImpl Class

The ViewRowImpl class is the base class for view row objects.

E.2.7.1 Methods You Typically Call on ViewRowImpl

Table E-24 describes the operations that you can perform on a view object row using your custom ViewRowImpl class.

Table E-24 Methods You Typically Call on ViewRowImpl

If you want to... Call this method in your custom ViewRowImpl class

Perform any of the common view row operations from inside your class, which can also be done from the client

For more information about the row-level operations, see Section E.1.6, "Row Interface."

Get the value of an attribute

getAttrName()

Set the value of an attribute

setAttrName()

Access the underlying entity instance to which this view row is delegating attribute storage

getEntityUsageAliasName()

Notes:

You can change the name of the entity usage alias name on the Entity Objects page of the Edit View Object dialog.


E.2.7.2 Methods You Typically Write in Your Custom ViewRowImpl Class

Table E-25 describes the operations that you can perform on a view object row using your custom ViewRowImpl class.

Table E-25 Methods You Typically Write on ViewRowImpl

If you want to... Write a method like this in your custom ViewRowImpl class

Calculate the value of a view object-level transient attribute

getAttrName()

Notes:

JDeveloper generates the skeleton of the method for you, but you need to write the custom calculation logic inside the method body.

Perform custom processing of the setting of a view row attribute

setAttrName()

Notes:

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

Determine the updateability of an attribute in a conditional way

isAttributeUpdateable()

Expose logical operations on the current row, optionally callable by clients

doSomething()

Notes:

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 can generate a custom YourViewObjectNameRow interface containing view row custom methods that you've chosen to expose to the client. You can use the Client Row Interface page of the Edit View Object dialog to select the methods that you want to appear in your client interface.

E.2.7.3 Methods You Typically Override in Your Custom ViewRowImpl Subclass

Table E-26 describes the operations that you can perform on a view object row using your custom ViewRowImpl subclass.

Table E-26 Methods You Typically Override in Your Custom ViewRowImpl Subclass

If you want to... Write a method like this in your ViewRowImpl subclass

Determine the updateability of an attribute in a conditional way

isAttributeUpdateable()


E.2.8 Setting Up Your Own Layer of Framework Base Classes

Before you begin to develop application-specific business components, you can create a layer of classes that extend all of the ADF Business Components framework base implementation classes described in this appendix. An example of a customized framework base class for application module components might look like this:

package com.yourcompany.adfextensions;
import oracle.jbo.server.ApplicationModuleImpl;
public class CustomApplicationModuleImpl extends ApplicationModuleImpl {
  /*
   * We might not yet have any custom code to put here yet, but
   * the first time we need to add a generic feature that all of
   * our company's application modules need, we will be very happy
   * that we thought ahead to leave ourselves a convenient place
   * in our class hierarchy to add it so that all of the application
   * modules we have created will instantly benefit by that new feature,
   * behavior change, or even perhaps, bug workaround.
   */
}

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:

  • public class CustomEntityImpl extends EntityImpl

  • public class CustomEntityDefImpl extends EntityDefImpl

  • public class CustomViewObjectImpl extends ViewObjectImpl

  • public class CustomViewRowImpl extends ViewRowImpl

  • public class CustomApplicationModuleImpl extends ApplicationModuleImpl

  • public class CustomDBTransactionImpl extends DBTransactionImpl2

  • public class CustomDatabaseTransactionFactory extends DatabaseTransactionFactory

For completeness, you may also want to create customized framework classes for the following classes as well:

  • public class CustomViewDefImpl extends ViewDefImpl

  • public class CustomEntityCache extends EntityCache

  • public class CustomApplicationModuleDefImpl extends ApplicationModuleDefImpl

Overriding anything in these classes would be a fairly rare requirement.