Skip Headers
Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers
10g (10.1.3.1.0)

Part Number B25947-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

D.2 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:

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

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

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

D.2.2.1 Methods You Typically Call on ApplicationModuleImpl

{para}?>

Table D-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

See the Section D.1.1, "ApplicationModule Interface" section above.

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

getViewObjectInstanceName()

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.

Access the current DBTransaction object

getDBTransaction()

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

getAppModuleInstanceName()

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.


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

{para}?>

Table D-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()

Note:

Use appropriate method on the DBTransaction interface to create a JDBC PreparedStatement. If the stored procedure has OUT parameters, 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.

Expose custom business service methods on 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 YourApplicationModuleName interface 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.

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

{para}?>

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

If you want to... Override this method of the 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()

Note:

This is the method you'd use to setup per-client context info for the current user in order to use database 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 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 code after the application module's transaction is associated with a database connection from the connection pool.

afterConnect()

Note:

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.

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

beforeDisconnect()

Note:

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()


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

D.2.3.1 Methods You Typically Call on DBTransaction

{para}?>

Table D-13 Methods You Typically Call on DBTransaction

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

Commit the transaction

commit()

Rollback 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()


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

{para}?>

Table D-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 to have your custom DBTransactionImpl2 subclass get used at runtime, there are two steps you must follow:

  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.

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

D.2.4.1 Methods You Typically Call on EntityImpl

{para}?>

Table D-15 Methods You Typically Call on EntityImpl

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

Get the value of an attribute

getAttributeName()

Note:

Code-generated getter method calls getAttributeInternal() but provides compile-time type checking.

Set the value of an attribute

setAttributeName()

Note:

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 UI's refresh 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 in the current transaction (but not yet committed)

getEntityState()

Note:

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()

Note:

This method is typically only relevant 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()


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

{para}?>

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

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

Perform attribute-specific validation

public boolean validateSomething(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 validation

public boolean validateSomething()

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 of a transient attribute

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


D.2.4.3 Methods You Typically Override on EntityImpl

{para}?>

Table D-17 Methods You Typically Override on EntityImpl

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

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

create()

Note:

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

Modify attribute values before changes are posted to the database

prepareForDML()

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

doDML()

Note:

Check 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()

Note:

If the parent entity is related to this child entity via a composition association, then the framework already handles this automatically. If they 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 overridden postChanges() method to accomplish this.



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


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 — 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 Oracle ADF would have done by default, which is non-trivial and a chore to remember and hand-code each time.


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

D.2.5.1 Methods You Typically Call on EntityDefImpl

{para}?>

Table D-18 Methods You Typically Call on EntityDefImpl

If you want to... Call the EntityDefImpl method

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

findByPrimaryKey()

Note:

See this tip for getting findByPrimaryKey() to find entity instances of subtype entities as well.

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()

Note:

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 cache of this entity type.

getAllEntityInstancesIterator()

Access ArrayList of entity definition objects for entities that extend the current one.

getExtendedDefObjects()


D.2.5.2 Methods You Typically Write on EntityDefImpl

{para}?>

Table D-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)

Note:

Internally, this 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 the method is public if other classes need to be able to call it.


D.2.5.3 Methods You Typically Override on EntityDefImpl

{para}?>

Table D-20 Methods You Typically Override on EntityDefImpl

If you want to... Call the EntityDefImpl method

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()

Note:

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 doesn't support RETURNING INTO at the database level.

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

isUpdateChangedColumns()

Note:

Defaults to true.

Find any EntityDefImpl object by its fully-qualified name

findDefObject()

Note:

Static method.

Set the value of an entity object's custom property

setProperty()

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

createInstance()

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.


D.2.6 ViewObjectImpl Class

The ViewObjectImpl class the base class for view objects.

D.2.6.1 Methods You Typically Call on ViewObjectImpl

{para}?>

Table D-21 Methods You Typically Call on ViewObjectImpl

If you want to... Call this ViewObjectImpl method

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

See the Section D.1.3, "ViewObject Interface", Section D.1.4, "RowSet Interface", and Section D.1.5, "RowSetIterator Interface" sections above.

Set an additional runtime WHERE clause on the default rowset

setWhereClause()

Defines a named bind parameter.

defineNamedWhereClauseParam()

Removes a named bind parameter.

removeNamedWhereClauseParam()

Set bind variable values on the default rowset by name. Only works when you have formally defined named bind variables on your view object.

setNamedWhereClauseParam()

Set bind variable values on the default rowset. Use this method for view objects with binding style of "Oracle Positional" or "JDBC Positional" when you have not formally defined named bind variables.

setWhereClauseParam()

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

getFilteredRows()

Retrieved 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 round-trip for this view object.

setFetchSize()

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.


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

{para}?>

Table D-22 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 set bind variable values without exposing positional details of the bind variables themselves

someMethodName(Type1arg1, ..., TypeNargN)

Note:

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


JDeveloper 10g can generate you a custom YourViewObjectName interface 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.

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

{para}?>

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

If you want to... Override this ViewObjectImpl method

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

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

executeQueryForCollection()

Change/augment the way that the ViewCriteria collection of ViewCriteriaRows is converted into a query-by-example WHERE clause.

getViewCriteriaClause()


D.2.7 ViewRowImpl Class

The ViewRowImpl class the base class for view row objects.

D.2.7.1 Methods You Typically Call on ViewRowImpl

Table D-24 Methods You Typically Call on ViewRowImpl

If you want to... Write a method like this 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

See the Section D.1.6, "Row Interface" section above.

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()

Note:

You can change the name of the entity usage alias name on the Entity Objects tab of the View Object Editor


D.2.7.2 Methods You Typically Write on ViewRowImpl

{para}?>

Table D-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()

Note:

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()

Note:

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()

Custom methods that expose logical operations on the current row, optionally callable by clients

doSomething()

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 YourViewObjectNameRow interface 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.

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

{para}?>

Table D-26 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 conditional way.

isAttributeUpdateable()


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

Before you begin to develop application specific business components, Oracle recommends 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:

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, but overriding anything in these classes would be a fairly rare requirement.

  • public class CustomViewDefImpl extends ViewDefImpl

  • public class CustomEntityCache extends EntityCache

  • public class CustomApplicationModuleDefImpl extends ApplicationModuleDefImpl