You are on page 1of 40

Programmatically Customizing Data Services

Copyright 2008, Oracle. All rights reserved.


Objectives

After completing this lesson, you should be able to do the


following:
Generate Java classes for business components
Override class methods
Implement programmatic modifications
Add service methods to an application module
Create a test client
Use business component client APIs

8-2 Copyright 2008, Oracle. All rights reserved.


Generating Java Classes for Adding Code

To generate a Java class:


1. On the business component editors Java page, click Edit
2. Select classes to generate

8-3 Copyright 2008, Oracle. All rights reserved.


Programmatically Modifying the Default
Behavior of Entity Objects

Many modifications are possible with coding, such as:


Traversing associations
Overriding base class methods

8-4 Copyright 2008, Oracle. All rights reserved.


The Supporting Entity Java Classes

EntityImpl
The entity class
Represents a row
Provides getter and
setter methods
EntityDefImpl
The entity definition class
Represents the whole entity
Can be used to modify the entity definition
EntityCollImpl
Represents the cached set of rows from the entity
Not usually necessary to modify or override methods in this
class

8-5 Copyright 2008, Oracle. All rights reserved.


Traversing Associations

PersonEOToOrderEO
OrderEO
PersonEO
getPersonEO()
getOrderEO() setPersonEO()
getEmail() getPersonEmail()
Accessor in source Accessors in destination
to get destination to get and set source

The destination entitys EntityImpl.java file contains


methods to get and set the source entity. For example,
OrderEOImpl.java contains getPersonEO() and
setPersonEO().
You could add a method to OrderEO.java to get the
email address of the associated person (customer):

public String getPersonEmail() {


return getPersonEO().getEmail(); }

8-7 Copyright 2008, Oracle. All rights reserved.


Overriding Base Class Methods

You can override methods in


the base classes for objects.
For example, you can override
methods in EntityImpl.java,
such as:
doDML(): Use it to log
changes in another entity.
beforeCommit(): Use it to
validate multiple instances of the
same entity.
remove(): Use it to log a
deletion in an entity.

8-8 Copyright 2008, Oracle. All rights reserved.


Overriding Base Class Methods Example:
Updating a Deleted Flag
Instead of Deleting Rows

// In <Entity name>Impl.java

1 public void remove() {


setDeleted("Y");
super.remove();
}

2 protected void doDML(int operation,


TransactionEvent e) {
if (operation == DML_DELETE) {
operation = DML_UPDATE;
}
super.doDML(operation, e);
}

Overriding the remove() and doDML() methods

8-9 Copyright 2008, Oracle. All rights reserved.


Overriding Base Class Methods Example:
Eagerly Assigning Values
from a Database Sequence

// In ProductEOImpl.java
import oracle.jbo.server.SequenceImpl;
// Default ProdId value from PRODUCTS_SEQ sequence at
1 protected void initDefaults() {
2 super.initDefaults();
SequenceImpl sequence = new
3 SequenceImpl("PRODUCTS_SEQ",getDBTransaction());
DBSequence dbseq = new
4
DBSequence(seq.getSequenceNumber());
5 populateAttributeAsChanged(ProdId, dbseq);
}

Overriding the initDefaults() method

8 - 10 Copyright 2008, Oracle. All rights reserved.


Programmatically Modifying the Default
Behavior of View Objects

For example, you can:


Change the WHERE or ORDER_BY clause programmatically
Retain and reuse a row set
Traverse view links

8 - 11 Copyright 2008, Oracle. All rights reserved.


The Supporting View Object Java Classes

ViewObjectImpl
The view class
Provides methods
to manage the row
set
ViewDefImpl
The view definition class
Represents the whole view
Can be used to modify the view definition
ViewRowImpl
The view object row class
Instantiated for each record returned by the query
Provides attribute accessors

8 - 12 Copyright 2008, Oracle. All rights reserved.


Examining View Object Methods

Javadoc for the


ViewObjectImpl class

8 - 13 Copyright 2008, Oracle. All rights reserved.


Changing View Object
WHERE or ORDER BY Clause at Run Time
Database
Table
CustomerStatusRO
Name Status
ID NAME STATUS select name, Mike Silver
201 Susan Platinum status
from customers
Steve Gold
202 Mike Silver
201 Steve Gold order by name Susan Platinum

ViewObject vo = am.findViewObject Name Status


("CustomerStatusRO");
String whereClause = "NAME < 'Su'"; Steve Gold
String orderByClause = "STATUS"; Mike Silver
vo.setWhereClause(whereClause);
vo.setOrderBy(orderByClause);

8 - 16 Copyright 2008, Oracle. All rights reserved.


Using Named Bind Variables at Run Time

Assigning values to named bind variables at run time:


ViewObject vo = am.findViewObject("PersonView1");
vo.setNamedWhereClauseParam("TheName","alex%");
vo.executeQuery();

Adding named bind variables at run time:


vo.setWhereClause("person_type_code = :PersonType");
vo.defineNamedWhereClauseParam("PersonType", null, null);
vo.setNamedWhereClauseParam("PersonType","STAFF");
// execute the query, process the results, and then later...
vo.setNamedWhereClauseParam("PersonType","CUST");
// execute the query, process the results

8 - 18 Copyright 2008, Oracle. All rights reserved.


Programmatically Retaining
and Reusing a View Link Accessor Row Set

To retain and reuse a view link accessor row set


programmatically:
1. Generate a Java class for the source view object.
2. Override the create() method.
3. Add setViewLinkAccessorRetained(true).
public class OrderVOImpl extends ViewObjectImpl {
public OrdersViewImpl() {
}
@Override
protected void create() {
super.create();
setViewLinkAccessorRetained(true);
}
}

4. Call reset() each time you reuse the RowSet object.


8 - 19 Copyright 2008, Oracle. All rights reserved.
Traversing Links

Links may be traversed in either direction.


ViewRowImpl.java contains a method to get the
associated row iterator.
For example, OrdersViewRowImpl contains the method:

public oracle.jbo.RowIterator getOrderItemsView ()

Use the methods of RowIterator to move from row to


row and to get individual attribute values.

8 - 20 Copyright 2008, Oracle. All rights reserved.


Application Module Files

Created by default:
<AppMod>AM.xml: Includes detailed metadata about the
View Objects included
bc4j.xcfg: Contains all the configuration and connection
details
Supporting Java classes:
<AppMod>AMImpl.java: Contains all the methods and
behaviors that affect each application module instance
<AppMod>AMDef.java: Contains methods to be used by
all instances of the application module

8 - 22 Copyright 2008, Oracle. All rights reserved.


Centralizing Implementation Details

Best practice is to place code in application module service


methods rather than in multiple clients.

X Code to
manipulate
view objects

Client Application Module

8 - 23 Copyright 2008, Oracle. All rights reserved.


Adding Service Methods
to an Application Module
Service methods:
Are useful for:
Code that is not dependent on a specific view
Performing operations across view object instances
Managing transactions
Dynamically changing the data model
Can be called from the client, requiring very little data
manipulation in the client itself
Are implemented in the application modules class
Are added by:
Adding code to the Java class
Publishing to the client interface

8 - 25 Copyright 2008, Oracle. All rights reserved.


Coding the Service Method

Add the Java code for the method to the


<AM_Name>AMImpl.java file.

8 - 27 Copyright 2008, Oracle. All rights reserved.


Publishing the Service Method

To publish the service method to clients:


1. Open the Application
Module Editor and
select the Java panel
2. Click the Pencil icon
to edit the Client
Interface
3. Shuttle the method
you want to publish
into the Selected list

8 - 28 Copyright 2008, Oracle. All rights reserved.


Testing Service Methods in the Business
Components Browser

Show the AM.

Select the method.


Set parameter values.

Click Execute.
Observe results.

8 - 30 Copyright 2008, Oracle. All rights reserved.


Accessing a Transaction

Transaction and DBTransaction are interfaces that


define database transactions.
Use the methods in these interfaces to access an
application modules transaction. For example:
ApplicationModuleImpl am; ...
// Commit the transaction
am.getTransaction().commit();

8 - 31 Copyright 2008, Oracle. All rights reserved.


Committing Transactions

Post phase

1. Validate pending changes.


2. Post updates to the database.

Commit phase

Commit the transaction.

8 - 33 Copyright 2008, Oracle. All rights reserved.


Customizing the Post Phase

Override the entity objects postChanges() method.


Example: For a deleted entity, mark the database row
instead of deleting the data.

public void postChanges(TransactionEvent e) {


if (getPostState() == Entity.STATUS_DELETED) {
// Custom code to mark database rows, such as
// by updating a Deleted flag in the record
}
else {
super.postChanges(e);
}
}

8 - 34 Copyright 2008, Oracle. All rights reserved.


Customizing the Commit Phase

Implement a TransactionListener.
Implement beforeCommit() and afterCommit().
Add your listener to the transactions list of
event subscribers.
Alternatively, override the entity objects
beforeCommit() or afterCommit() methods.
Example: In PersonEOImpl, print notification that record is committed:
@Override
public void afterCommit(TransactionEvent transactionEvent) {
System.out.println("Record committed for " +
getFirstName() + " " + getLastName());
super.afterCommit(transactionEvent);
}

8 - 35 Copyright 2008, Oracle. All rights reserved.


Using Entity Objects and Associations
Programmatically

Code to manipulate an entity object is typically placed in


an application module class or the class of another entity
object.
Typical tasks that you may need to code:
Finding an entity object by primary key
Updating or removing an existing entity row
Creating a new entity row

8 - 36 Copyright 2008, Oracle. All rights reserved.


Finding an Entity Object
by Primary Key

public String findOrderID(long orderId) {


String entityName = "oracle.fod.storefront.model.entity.OrderEO";
1 EntityDefImpl orderDef = EntityDefImpl.findDefObject(entityName);

2 Key orderKey = new Key(new Object[]{orderId});

3 EntityImpl order = orderDef.findByPrimaryKey(getDBTransaction(),


orderKey);
4 if (order != null) {
return (String)order.getAttribute(ShipToName"); }
else { return null; } }

8 - 37 Copyright 2008, Oracle. All rights reserved.


Updating or Removing
an Existing Entity Row

public void updateEmpEmail(long empId, String newEmail) {


1 EntityImpl emp = retrieveEmployeeById(empId);
if (emp != null) {
2 emp.setAttribute(Email",newEmail);
try {
3 getDBTransaction().commit(); }
catch (JboException ex) {
getDBTransaction().rollback();
throw ex; } } }

8 - 38 Copyright 2008, Oracle. All rights reserved.


Creating a New Entity Row

public long createProduct(String name, String description) {


String entityName = oracle. fod.storefront. model.entity.ProductEO";
1 EntityDefImpl productDef = EntityDefImpl.findDefObject(entityName);

2 EntityImpl newProduct =
productDef.createInstance2(getDBTransaction(),null);
newProduct.setAttribute("Name",name);
3 newProduct.setAttribute("Description",description);
try {
4 getDBTransaction().commit(); }
catch (JboException ex) {
throw ex; }
5 DBSequence newIdAssigned =
(DBSequence)newProduct.getAttribute("ProdId");
return newIdAssigned.getSequenceNumber().longValue();

8 - 39 Copyright 2008, Oracle. All rights reserved.


Using Client APIs

Client interfaces in the oracle.jbo package include:


ApplicationModule
ViewObject
Row
(But NOT Entity)

8 - 41 Copyright 2008, Oracle. All rights reserved.


Creating a Test Client

[Ctrl]+[Enter]

Need to modify names in


generated skeleton code
to reflect your AM
package and name and
VO instance name.

8 - 42 Copyright 2008, Oracle. All rights reserved.


Using View Objects in Client Code

Examples of using view objects programmatically:


Using query results programmatically
Using view criteria to alter view object queries at run time
Iterating masterdetail hierarchy
Finding a row and updating a foreign key value
Creating a new row

8 - 43 Copyright 2008, Oracle. All rights reserved.


Using Query Results Programmatically

ViewObject
setWhereClause
Row RowSet setNamedWhereClauseParam setNamedWhereClauseParam
Row executeQuery executeQuery
Row
hasNext hasNext hasNext
RowSetIterator
next next next

8 - 44 Copyright 2008, Oracle. All rights reserved.


Using View Criteria Programmatically

ViewCriteria vc = custOrdVO.createViewCriteria(); 1

ViewCriteriaRow promotionRow = vc.createViewCriteriaRow();


2
ViewCriteriaRow noPromRow = vc.createViewCriteriaRow();
promotionRow.setAttribute("OrderTotal", "> 500");
promotionRow.setAttribute("CreditLimit", "> 2500");
promotionRow.setAttribute(DiscountId", <> NULL"); 3
noPromRow.setAttribute("OrderTotal", "> 1000");
noPromRow.setAttribute(CreditLimit", "> 5000");

vc.addElement(promotionRow); 4
vc.addElement(noPromRow);
5
custOrdVO.applyViewCriteria(vc);
6
custOrdVO.executeQuery();

8 - 45 Copyright 2008, Oracle. All rights reserved.


Iterating MasterDetail Hierarchy

public class TestClient {


public static void main(String[] args) {
TestClient testClient = new TestClient();
String amDef = "oracle.hr.test.TestAM";
String config = "TestAMLocal";
ApplicationModule am =
Configuration.createRootApplicationModule(amDef,config);
1 ViewObject dept = am.findViewObject("DepartmentsView1");
dept.executeQuery();
2
while (dept.hasNext()) {
3 Row department = dept.next();
System.out.println("Department " +
4 department.getAttribute("DepartmentId"));
RowSet emps = (RowSet)department.getAttribute("EmployeesView");
5
while (emps.hasNext()) {
6 Row emp = emps.next();
System.out.println(" Employee Name: " +
7 emp.getAttribute("LastName")); }}
Configuration.releaseRootApplicationModule(am,true);}}

8 - 47 Copyright 2008, Oracle. All rights reserved.


Finding a Row and Updating
a Foreign Key Value
public class TestClient {
public static void main(String[] args) {
TestClient testClient = new TestClient();
String amDef = "oracle.hr.test.TestAM";
String config = "TestAMLocal";
ApplicationModule am =
Configuration.createRootApplicationModule(amDef,config);
1 ViewObject vo = am.findViewObject("EmployeesView1");
2 Key empKey = new Key(new Object[]{101});
3 Row[] empsFound = vo.findByKey(empKey,1);
if (empsFound != null && empsFound.length > 0) {
Row emp = empsFound[0];
4 System.out.println("Employee Name: " + emp.getAttribute("LastName"));
System.out.println("Employee is in department +
5 emp.getAttribute("DepartmentId"));
6 emp.setAttribute("DepartmentId",60);
System.out.println("Employee reassigned to department " +
7 emp.getAttribute("DepartmentId"));
8 am.getTransaction().rollback();
System.out.println("Transaction cancelled");}
Configuration.releaseRootApplicationModule(am,true); }}

8 - 48 Copyright 2008, Oracle. All rights reserved.


Creating a New Row

public class TestClient {


public static void main(String[] args) {
TestClient testClient = new TestClient();
String amDef = "oracle.hr.test.TestAM";
String config = "TestAMLocal";
ApplicationModule am =
Configuration.createRootApplicationModule(amDef,config);
1 ViewObject vo = am.findViewObject("EmployeesView1");
Row newEmp = vo.createRow();
2 vo.insertRow(newEmp);
newEmp.setAttribute("EmployeeId",999);
newEmp.setAttribute("FirstName","Pam");
3 newEmp.setAttribute("LastName","Gamer");
Date now = new Date();
newEmp.setAttribute("HireDate",now);
newEmp.setAttribute("JobId","IT_PROG");
newEmp.setAttribute("Email","pgamer@mymail.com");
newEmp.setAttribute("DepartmentId",60);
newEmp.setAttribute("ManagerId",103);
am.getTransaction().commit();
4
System.out.println("Added employee " +
5 newEmp.getAttribute("EmployeeId") + " to Department " +
newEmp.getAttribute("DepartmentId"));
Configuration.releaseRootApplicationModule(am,true); }}

8 - 49 Copyright 2008, Oracle. All rights reserved.


Summary

In this lesson, you should have learned how to:


Generate Java classes for business components
Override class methods
Implement programmatic modifications
Add service methods to an application module
Create a test client
Use business component client APIs

8 - 50 Copyright 2008, Oracle. All rights reserved.


Practice 8 Overview:
Programmatically Modifying
Business Components

This practice covers the following topics:


Generating Java classes
Overriding base class methods
Using a test client to enable testing code that uses some of
the view object APIs
Extending the application module base class
Adding service methods to an application module

8 - 51 Copyright 2008, Oracle. All rights reserved.

You might also like