Skip Headers
Oracle® Fusion Applications Developer's Guide
11g Release 1 (11.1.2)

Part Number E15524-02
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

9 Using Fusion Middleware Extensions for Oracle Applications Base Classes

This chapter describes the Fusion Middleware extensions for Oracle Applications base classes that extend the features of standard ADF Business Components classes.

The chapter includes the following sections:

9.1 Introduction to Fusion Middleware Extensions for Oracle Applications Base Classes

Fusion Middleware extensions for Oracle Applications base classes provide additional features that are not part of the standard ADF Business Components core entity objects, view objects, and application modules.

The Fusion Middleware extensions support the following standard Oracle Applications features:

The base classes extend ADF Business Components Entity, EntityDef, ViewObject, ViewRow, and ApplicationModule implementation classes.

The base classes provided by Fusion Middleware extensions are the following:

They are found in oracle.apps.fnd.applcore.oaext.model.package and extend the JBO classes with the same name (but without the OA prefix) in oracle.jbo.server.package.

In Oracle JDeveloper, selecting the Oracle Fusion Applications Developer role automatically sets the Fusion Middleware extensions for Oracle Applications base classes as the default classes for ADF Business Components objects. The base classes become available when you add the Applications Core library. For more information, see Chapter 2, "Setting Up Your Development Environment."

9.2 Using Multi-Language Support Features

Multi-language support (MLS) gives Oracle the ability to ship its products in multiple languages by setting standards and guidelines for translation.

In JDeveloper, multi-language entities are those that maintain one or more translated attributes and require the storage of all relevant translations of these attributes. Such entities have a base table that has attributes that are not translated and do not vary by language (such as codes and IDs) and a TL table that has, in addition to the base table primary key, the translatable attributes for that entity (such as Display Name, and Application Name). Figure 9-1 illustrates this concept.

Figure 9-1 Multi-Language Entity Tables

Multi-Language Entity Tables

For each row in the base table, there will be as many rows in the translation table as there are installed languages. The translation table's primary key is made up of the foreign key to the base table and a language column, which may be viewed as a foreign key to the FND_LANGUAGES table.

The translation table is fully populated. This means that rows for all installed languages are inserted even if the actual translations for these languages are not yet available. The logic, which maintains multi-language entities, is responsible for ensuring that the translation rows are inserted, updated, or deleted as required to meet the "fully populated" requirement. Translations, which have not been supplied, must be defaulted from one of the available translations. As updates occur to supply missing translations, the default values will be converted to true translations.

Since applications are run in a single language for any given user session, a convenient view is provided for the multi-language entities, which joins the base table and translation table and filters translations to the runtime language. This is the Multi-language View. This view uses the userenv ('LANG') expression to select the correct translation based on the session language, which usually comes from the NLS_LANG environment variable.

The following extensions support TL tables:

As a developer, you can use multi-language extensions to deal with only one entity that contains both translatable and non-translatable attributes, instead of having to deal with two entities, one for the base table and one for the translation table.

Whenever an entity is created, the extensions ensure that the TL entities are also created for every installed language in the environment.

Whenever an insert is made into the base table or the table is updated, the same operations must also be performed on the corresponding TL table. Behind the scenes, the extensions override the appropriate ADF Business Components methods, such as create() and setAttribute(), to ensure that the TL table is populated correctly.

The extensions also enable you to work with only one ADF Business Components entity object at runtime for a multi-language database entity, and shield you from the two underlying tables (base and multi-language) that hold the data. You will see no inherent difference between a multi-language entity and a standard one. In addition, the extensions allow you to define an entity as multi-language in a JDeveloper design time environment, and provide any additional metadata for such that entity.

9.2.1 Using Utility APIs

In addition, the following utility APIs are provided in OAEntityImpl:

  • public boolean isTranslatable () - Returns true if this entity is a translatable entity.

  • public boolean isTranslated () - Returns true if there is at least one translated language other than the base language for this entity.

  • public String [] getTranslatedLanguages () - Returns an array of Language codes for which actual translations exist. The list always returns the base language as one of the translated languages. A record is considered translated if the LANGUAGE and SOURCE_LANG columns are equal.

The same set of APIs also will be provided on the AViewRowImpl object, since it also would have the same characteristics of a row.

9.2.2 How to Create a Multi-Language ADF Business Components Entity Object

Creating a multi-language ADF Business Components entity object consists of four tasks:

Task 1   Create an entity object for a _TL table

To create an entity object for translatable (_TL) tables, perform the following procedure.

Note:

This procedure does not apply to a _VL view. For information about creating an entity object for a _VL view, see Task 2, "Create an entity object for a base table".
  1. Name the entity <Entity>TranslationEO.

    For example, for a table named FND_ITEMS_DEMO_TL, you can name the entity ItemsDemoTranslationEO.

  2. Include all of the table's attributes.

    Make sure the attribute for the LANGUAGE column is named Language, and the attribute for the SOURCE_LANG column is named SourceLang.

    If your TL table columns for LANGUAGE and SOURCE_LANG are named differently, it is important that you still name the attributes Language and SourceLang.

  3. Identify the table's primary keys, including the LANGUAGE column.

  4. Verify that this extends OAEntityImpl like any other entity object.

  5. Add whatever validation logic you need for this entity and its attributes.

    The translatable values are unlikely to need any special validation.

Overriding the default attribute behavior:

By default, all the attributes in the _TL table will be considered translatable if they are:

  • not a primary key attribute

  • not an entity accessor

  • one of the following types: VARCHAR, CHAR, FIXED_CHAR, LONGVARCHAR, CLOB

Note:

SourceLang and Language are special attributes and are handled by Oracle Fusion Middleware Extensions for Applications.
Task 2   Create an entity object for a base table

To create an entity object for a base table, perform the following procedure.

  1. Name the entity object.

    Use the regular entity object naming convention. For example, for the FND_ITEMS_DEMO table, the corresponding entity would be named ItemsDemoEO. The entity should be based on the _VL view.

  2. Include all columns except the RowId pseudo-column in the view.

  3. Identify your primary keys as you normally would.

  4. Set the entity-level Oracle Fusion Middleware Extensions for Applications schema-based ADF Business Components property named fnd:OA_BASE_TABLE with a value that names the true base table of your translatable entity.

    For example, for the FND_ITEMS_DEMO_VL view, this value would be set to FND_ITEMS_DEMO_B.

    You could use the entity Property Inspector to set this property, as shown in Figure 9-2.

    Figure 9-2 Entity Property Inspector

    Entity Property Inspector

Oracle Fusion Middleware Extensions for Applications automatically overrides the entity's doDML() method to ensure that all inserts, updates, and deletes are actually performed on the base table identified by this property. All reads will be done against the _VL view.

Task 3   Associate the _VL view and _TL table entity objects

To create the association between the _VL view and _TL table entity objects, perform the following procedure.

  1. Follow the standard association object naming convention that describes the entity relationships. For example, ItemsToTranslation.

  2. In the Structure window, choose the entity object. In this case, it is ItemsToTranslation.

  3. In the Overview window, choose the Relationship option.

  4. Designate the association as a Composition Association with a 1:* cardinality, as shown in Figure 9-3.

    Figure 9-3 Composition Association

    Composition Association

    When you select Composition Association, be sure to uncheck Implement Cascade Delete and Cascade Update Key Attributes if they are selected.

  5. Select the base entity as the source and the _TL entity as the destination.

    Since the Applications Core OAEntityImpl class overrides the remove() method on the EntityImpl class to handle Translation rows deletion, Cascade Delete is not required.

  6. Configure Source Accessor and Destination Accessor, as shown in Figure 9-4.

    Note:

    Ensure that the Source Accessor has been created prior to performing Step 6.

    Figure 9-4 Association Properties

    Association Properties
Task 4   Create a view object that uses a translatable entity

When creating the view objects that will access your translatable tables, keep in mind the following:

  • Always use the base entity object created for the _VL view. For example, ItemsDemoEO.

  • Do not use the _Translation entity object ItemsDemoTranslationEO directly. For the purpose of any code that needs to access your translatable entity, you should treat the base entity object as the only entity object. Coordination between the base and Translation entities is handled automatically and the Translation entity should remain "invisible". Otherwise, you can treat your base entity object like any other entity object.

For a _TL table with no corresponding _B table:

There may be a rare case where you have a _TL table and _VL view and no _B table, because all of the attributes are translatable. If this occurs, do the following:

  1. Define the base entity on the database view _VL.

  2. Set the Applications Core schema-based property fnd:OA_BASE_TABLE to be the _VL view name.

  3. Override doDML() for the base entity to do nothing. This is going to be a virtual entity that does not have an underlying database table.

  4. Create the translation entity object and the composite association between the base entity and the translation entity as you would in the regular scenario.

    The Translation EO in this scenario alone must also include the non-translatable attributes because the base entity's doDML() does nothing. If the translation entity does not include non-translatable attributes, you might get exceptions saying the attribute is not populated

  5. Mark all the non-translatable columns in the _TL entity, i.e., non-string fields and non-primary keys, as explicitly translatable by setting OA Translatable to true in the Applications section of the Property Inspector, as shown in Figure 9-5.

    Figure 9-5 OA Translatable Setting

    OA Translatable Setting

    By default, only string fields (VARCHAR2 and its variants) are identified as translatable automatically by the parent. Primary key changes on the entity are also handled automatically by the framework. This means any numeric, date, or other data type attributes that are not primary key need to have the OA Translatable property set explicitly to true.

    There is a slight downside to this approach as non-translatable columns (like numbers and dates), technically, are being marked as translatable. However, this approach is required in order to ensure attributes set on the base entity are propagated to the TL entity; otherwise, you will get an "attribute not populated" exception. This is needed because the base entity is virtual and the doDML() method on the base entity is empty.

9.2.2.1 What You Need to Know About Overrides

If you happen to override the create(AttributeList attributeList) method on your entity, do not forget to call super.create(attributeList) in the override method before invoking custom code. This is true in all scenarios.

9.3 Using WHO Column Features

The WHO feature reports information about who created or updated rows in Oracle Applications tables. Oracle Applications upgrade technology relies on WHO information to detect and preserve customizations. ADF Business Components provides the ability to track the creation of an entity or the changes made to one.

The OAEntityImpl populates the WHO columns automatically. In addition to the standard history columns supported by ADF Business Components, the extension provides support for Last Update Login field.

All WHO columns are updated based on the current User Session. Table 9-1 lists the WHO columns and their descriptions.

Table 9-1 WHO Column Summary

Column Name Type Null? Description

CREATED_BY

VARCHAR2(64)

NOT NULL

Keeps track of which user created each row.

CREATION_DATE

DATE

NOT NULL

Stores the date on which each row was created.

LAST_UPDATED_BY

VARCHAR2(64)

NOT NULL

Keeps track of who last updated each row.

LAST_UPDATE_DATE

DATE

NOT NULL

Stores the date on which each row was last updated.

LAST_UPDATE_LOGIN

VARCHAR2(32)

 

Stores the Session ID of the user who last updated the row.


9.3.1 How to Use the Extension

In order for Oracle Fusion Middleware Extensions for Applications to populate your WHO columns automatically, ensure that your WHO column attributes are of the appropriate History Column type by using the Entity Attribute Wizard, as shown in Figure 9-6.

Figure 9-6 Entity Attribute Wizard: LastUpdateDate

Entity Attribute Wizard: LastUpdateDate

In the example entity, the WHO column LastUpdateDate is identified as a modified on History Column type.

Similarly, identify the following attributes as indicated:

  • LastUpdatedBy - modified by

  • CreationDate - created on

  • CreatedBy - created by

Ensure that the LAST_UPDATE_DATE and CREATION_DATE WHO columns have the Type as Timestamp (java.sql.Timestamp), as shown in Figure 9-7.

Figure 9-7 Timestamp (java.sql.Timestamp)

Timestamp (java.sql.Timestamp)

9.3.2 What Happens with WHO Column at Design Time and Runtime

WHO column features provide the following design time and runtime support:

  • The extension supports the LAST_UPDATE_LOGIN column and ensures that the other columns are populated correctly.

  • The LAST_UPDATED_BY and CREATED_BY columns are populated with a value based on the user name, and not with the user GUID, a user ID, or a session ID. To obtain the value to populate these columns in PL/SQL, use FND_GLOBAL.WHO_USER_NAME. In Java, the CreatedBy and LastUpdatedBy attributes will normally be populated automatically with the correct value by the base classes, or you can also obtain the value from OAEntityImpl.getWhoUser().

  • History is provided for the Session ID of the user who last updated the row.

  • Proper shaping in the Oracle Fusion Applications Developer role to make this history available.

9.4 Using PL/SQL-Based Entities

PL/SQL entities are those that depend on PL/SQL packages to handle their Data Manipulation Language (DML) operations (insert, delete, update, and lock). Since Oracle Applications has a large amount of their business logic in PL/SQL and a lot of teams still use it, they need a mechanism that will allow them to use their PL/SQL code when building ADF Business Components entities. The Fusion Middleware extensions provide the following:

9.4.1 How to Use APIs to Facilitate DML Operations

In addition, the following APIs are provided in the OAEntityImpl class to facilitate the insert, update, and delete DML operations in PL/SQL:

  • protected void insertRow ();

  • protected void updateRow ();

  • protected void deleteRow ();

The default implementations of these methods delegate to super.doDML (operation), which will result in SQL insert/update/delete being called for the entity.

9.4.2 How to Use the Extensions

A PL/SQL-based entity object provides an object representation of the data from a table or view and routes the DML operations to stored procedures in the database.

To identify an entity as a PL/SQL one, a custom attribute, OA_PLSQL_ENTITY, must be set to Y (Yes). This allows the framework to identify this entity as PL/SQL based.

To identify an entity as a PL/SQL one:

  1. From the Applications window, choose an entity object.

  2. In the Structure window, highlight the entity object.

  3. From the Property Inspector tab, choose the Applications option.

  4. Under PL/SQL, select Y from the OA PLSQL Entity dropdown menu, as shown in Figure 9-8.

    Figure 9-8 OA PLSQL Entity Setting

    OA PLSQL Entity Setting
  5. Override the following methods for its DML operations and provide JDBC calls when applicable:

    • void insertRow();

    • void updateRow();

    • void deleteRow();

    Use the PL/SQL entity objects only if you have legacy PL/SQL code that maintains all your transactions and validations. If you are working on a new product and/or do not have a lot of PL/SQL legacy code, Applications Core recommends the use of Java entity objects over PL/SQL entity objects.

  6. Call your PL/SQL insert, update, or delete procedure in your void insertRow();, void updateRow();, or void deleteRow(); method without calling super().

  7. Create a callable statement to invoke your PL/SQL method.

  8. Validate your attributes. You can do this in either of two places:

    • In your insertRow() or updateRow() methods: Perform your validation in Java in either of these two methods, or in PL/SQL stored procedures called from the methods.

    • In your validateEntity() method: If validations are done in a separate stored procedure in PL/SQL, you can call that stored procedure in this method.

9.4.3 What Happens with PL/SQL Entities at Design Time and Runtime

The extensions provide the following design time and runtime support:

  • Provides the ability to identify PL/SQL-based entities.

  • Invokes PL/SQL for DML operations.

9.5 Accessing FND Services

Fusion Middleware extensions for Oracle Applications provide the following services:

Fusion Middleware extensions provide an easy way to access these services and to invoke them. Typically, the services are provided as application modules. An application module serves as a container for the various view objects and provides business-service-specific functionality.

The services listed above are provided as a service-specific application module. For example, Profile functionality is made available in ProfileService.

Access to these services is provided as a getFNDNestedService (String service) method in the OAApplicationModuleImpl class. The OAApplicationModuleImpl extension is used to support access to the services.

See Section 9.5.1, "How to Use the Extension," for implementation information.

9.5.1 How to Use the Extension

The code in Example 9-1 shows how to provide access to an FND service. In this case, it is ProfileService.

Example 9-1 Accessing an FND Service

ProfileService profileService = (ProfileService) myAM.getFNDNestedService (OAConstants.PROFILE_SERVICE);
// now call profile specific methods on the ProfileService AM
String appsServletAgent = profileService.getProfile ("APPS_SERVLET_AGENT");

OAConstants exposes the various service names as a constant.

Note that the getFNDNestedService () is just a utility method that looks up the rootAM and checks to see if an instance of the requested service already exists in the rootAM as a nested AM. If one exists, it will return it; if it does not, it will instantiate a new AM for that service that will be nested inside the rootAM and return it.

9.6 Using Unique ID

In order to avoid primary key collision issues when synchronizing with disconnected clients, Oracle Applications standards require that an ADF Business Components entity object's primary key be populated with a Unique ID.

Fusion Middleware extensions support Unique ID by allowing an entity attribute to be populated with a globally unique value. The Fusion Unique ID Generator provided by ADF Business Components does this. The Unique ID can be used to populate an entity attribute of the BigDecimal and Long data types. The Unique IDs generated are of the BigDecimal type and meet certain criteria for uniqueness across database instances.

Notes:

The database table column data type that corresponds to the entity attribute requiring a Unique ID must be large enough to hold the uniquely generated value. Typically, it should be of type NUMBER(18). NUMBER(15) may not be sufficient to hold the uniquely generated values.

In addition, Oracle Applications coding standards require that the entity attribute populated with a Unique ID be of type Long.

9.6.1 How to Use the Extension

Fusion Middleware extensions provide both design time and runtime support for Unique ID.

9.6.2 What Happens with Unique ID at Design Time

At design time, Fusion Middleware extensions provide the ability to identify if an entity attribute needs a globally Unique ID. This is accomplished by setting Application Unique ID to true in the entity attribute's Property Inspector section, as shown in Figure 9-9.

Figure 9-9 Application Unique ID

Application Unique ID

9.6.3 What Happens with Unique ID at Runtime

Based on the design time setting, the framework populates the entity attribute with a globally unique value at runtime. This is accomplished by setting the following transient expression on the entity attribute's definition:

oracle.jbo.server.uniqueid.UniqueIdHelper.getUniqueId(adf.object.unwrapObject());

9.7 Using Data Security

Any custom view criteria adapter created by a product team will need to extend the OAViewCriteriaAdapter class in order for Data Security to work correctly.

By setting custom ADF Business Components properties at runtime, the OAApplicationModuleImpl class establishes the OAViewCriteriaAdapter class as the standard view criteria adapter for the ADF Business Components container.

9.7.1 How to Use the Extension

Product teams can do the following to create and use a custom view criteria adapter:

  1. Extend OAViewCriteriaAdapter and invoke super methods for use cases not handled by the custom view criteria adapter.

  2. Set the custom view criteria adapter by invoking the setViewCriteriaAdapter() method in the create() method of the custom ViewObjectImpl class.

  3. Set the custom view criteria adapter on the ViewObject.

9.8 Using Document Sequencing

Document sequencing is a way to uniquely identify all business documents and business events belonging to a legal entity.

Document-sequence numbering has many country-specific requirements. It is a legal requirement in many EMEA, Asia Pacific, and Latin American countries. In the United States and the United Kingdom, it is used for internal control purposes and for financial-statement and other audits.

For more information about ADF Business Components integration of this feature provided by Fusion Middleware extensions, see Chapter 11, "Setting Up Document Sequences."