Saturday, May 12, 2012

Common Mistakes in OAF

I have conducted a few corporate trainings, it was a good experience. I received positive feedback, which encouraged me further. On introspection I remembered a saying, “A poor student has good chance of becoming a good teacher”.

Poor students have to struggle hard to learn things, and excel. They can easily relate to participant's problems. They have less chances of taking things for granted and assuming that one would at least know this much. They can ensure that one feels comfortable sharing less intelligent thoughts, they may even relate to many of them. He can understand its not uncommon to do common and silly mistakes while on the learning curve.

Debatable !! Certainly when one of the best teachers I know is my dear friend Deepak Srivastava, who is a topper in School, College, and University. There are exceptions

We are diverting here.
So, following are some of the mistakes I have done over the years and I am totally cool about it. Given a chance I don't mind making more mistakes and learn from them:


1. Calling ProcessRequest from ProcessFormRequest.

This was during my first OAF search page was around 7.5 yrs back. Search page was different from the traditional search pages. This was done in an attempt to write less code. Later realized that significance and semantics of these methods and took corrective measures.


2. Traversing VO Rows directly without any iterator.

Ideally one should prefer using a RowSetIterator for navigating the rows.
If we choose to directly use the VO for navigating the rows using vo.first(), vo.hasNext(), vo.next(), etc methods, this would result in current row getting changed. If same VO is being used to display the result on the webpage, the change in current row will result in different rows being displayed in result table or form.


3. Using of getRowCount()

Worst reason to use getRowCount() could be
if(getRowCount() > 0)
getRowCount() always executes the VO.

4. Calling setters from getters.

Get Methods are not expected to change the value of the property and state of the object.


5. Coding PPR without CO and AM code

This might be a surprise to few but there is a terrible way to code PPR, following are the steps:
a) Enable PPR on the UI widget.
b) Don't handle anything in CO, no capturing the event.
c) Don't write any code for PPR in AM
d) All code in VO getters. Whenever a PPR event is fired, getters of all the fields being displayed will be fired.

Please don't follow above steps for the PPR.


6. Went overboard with generic APIs.

A good programmer writes the logic with KISS principle in mind. Too many generic APIs will make more slightly difficult to read. They are important but one shouldn't write an API for every piece of logic needed.

7. Keeping constants in a separate utility java file (for using it at many places in multiple java files) Compiling only this file after changing value of constant.

Java replaces the reference of constants to actual value of the constants in the .class file.
When you change the value of the constant in the utility java file, and compile, it doesn't replace the value of constant in existing compiled class files where this constant is being used. Existing class files will continue to use the old value of the constants.

8. Creating more transient attributes in VORowImpl than using calculated attributes and keeping code in SQL Queries.

Many times you have a choice to either create a transient variable in VO and calculate the value in VORowImpl or modify the SQL of the VO and calculated the value in SQL.
Both approaches are fine but doing it in SQL is better practice, makes code more readable and easy to maintain.

9. Ignoring the sequence of Form Value and other fields 

At times we have form values and other fields on a page, all binded to same VO Instance and VO Attribute.
Read Only widgets like MessageStyleText don't submit their data, we need Form Values to submit the data to BC4J. 

We need form values in case of dependent LOVs or other dependent widgets. 
We also need form values to submit the data shown to users as readonly which is returned by LOVs.

Now what is more important is to know how and in what order the values in the UI widgets gets transferred to BC4J. The sequence is from top to bottom. In case if there are more than one field in UI for a VO Attribute, then the last UI widget that can submit the value will set the value the last time and thus this will get saved in DB.
I ignored this and in a rare but a badly coded page of mine, this was cause of a bug.


10. Not enabling Passivation on AM

Please do not forget to enable Passivation on your AM.

11. Ignoring the Tuning Tab in VO

In VO properties, there is tuning tab, setting the properties helps improve the performance, and shouldn't be ignored.


12. Not writing re-enterable processRequest Code

The processRequest() method may be re-entered to synchronize UIX with BC4J. Any initialization logic (VO execution, session variables, transaction variables based logic) must keep this in mind.



13. Prefer Oracle-style binding (:1, :2) over JDBC Style(?)

      Oracle Style binding avoids parsing SQL at runtime to do String replacement.