Disclaimer

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.

Tuesday, October 13, 2009

Getting handle to HttpSession in ADF

However, in general you should not need to get HttpSession programmatically in ADF.

But sometimes you need and here is how:

FacesContext context = FacesContext.getCurrentInstance();

HttpSession session  = (HttpSession)context.getExternalContext().getSession()



Wednesday, September 9, 2009

Creating code templates in Jdeveloper 11g


Jdeveloper has a great feature called code templates. Jdeveloper comes with some pre-seeded code templates and provided the capability to users to define their own.

A code template is kind of short cut to generate a boiler plate code which you use heavily. For example, a for loop. You can simply type in code fori and press Ctrl + enter and it will automatically generate:

for(i=0;i<0;i++){
}

This could be a huge time saving. If you want to have look at what all code templates are available then you can go to Tools-->Preferences --> Code Editor -->Code templates. You will see a good number of typically used code templates. Some are:

To define your own code template stay in the same place and click on the Add button.
So, let say we want to define a code template for iterating using a RowSetIterator and the code could be like:

ViewObject vo = null; //actual code will get the instance from application module
RowSetIterator itr = null;
if (null != vo.findRowSetIterator("test")) {
itr = vo.findRowSetIterator("test");
}
else
{
itr = vo.createRowSetIterator("test");
itr.reset();
}

while(itr.hasNext())
{
Row row = itr.next();
//your row specific code here
}

So, to define it just type a short cut name "ri" and in description "iterate using RowSetIterator on VO"

Below in the code just paste the code given below.
ViewObject $vo$ = null; //get view object
RowSetIterator $itr$ = null;
if (null != $vo$.findRowSetIterator("test")) {
$itr$ = $vo$.findRowSetIterator("test");
}
else
{
$itr$ = $vo$.createRowSetIterator("test");
$itr$.reset();
}
while($itr$.hasNext())
{
Row $row$ = $itr$.next();
$end$
}

Where ever, you see a word enclosed in $$ that is a kind of place holder and will replace with some actual value when you will use it. There is a variables tab. As soon as you paste the above code in the code tab you will see some variables are automatically defined. In the variables tab you can change the default values as well. By default it will assign the value same as the text enclosed in $$ in your code template.

There are situations like in the above template when you may need to import some classes. To do that just go to imports tab and paste below code:
oracle.jbo.Row
oracle.jbo.RowSetIterator
oracle.jbo.ViewObject

So, above 3 classes will be automatically imported when you will type ri and press ctrl + enter along with the desired code.


Monday, September 7, 2009

Performance tuning : Fault-in behavior in ADF

Well these days I got some interest in performance improvements in ADF applications.
So, here is an interesting term 'fault-in'. Before, I tell what it is the thumb rule is "Try to avoid it.".

Normally, when you build your Model or business components you start with building entity objects. On an entity object you build one or more view depending upon the UI requirements.

If you go with default options of creating an updatable view object based on an entity object you get a sql query which is selecting all the entity attributes with no where clause which is called 'Deafult VO query'. So, say you have an entity object EmpEO based on an employee table with selected attributes empId, empName, empSalary and mgrId then you will get something like

SELECT EmpEO.empId, EmpEO.empName, EmpEO.emoSalary, EmpEO.mgrId
FROM employee

However, in real life we create VOs depending upon the UI page requirements. So, say we create VO choosing only empId, empName and empSalary. While creating UI say it is just required to show empId and empSalary from the VO instance. On running the page, which has a VO instance of this VO as a table, ADF framework queries all the rows from the employee table and create entity instances one per row having information about empId, and empSalary. It will not populate empName and mgrId from DB. The VO instance will have pointer for each vo instance row to the actual EO instance having data.

This is pretty smart as most of the times you might be only viewing data and in that case it saves time and memory by not populating entity instances with data you don't need. Now, imagine there is a update page based on this vo instance where you try to update the emp record with id 486. In the entity object you define a validation rule that empSalary of the employee being updated should not be higher than the salary of any of the employee under his manager. So, here fault-in comes to the picture. As mgrId is mentioned in the validation rule which is missing from VO definition so while checking for this validation on record commit, framework will fire the default VO query and hence will populate all the missing EO attribute information from DB for that row . That could cause performance overhead at run time. It may be fine for a case where there is just one missing attribute and your entity is based on a few attribute based table. But in a scenario where say your entity has 100 or more attributes in that case default VO query may be big performance overhead. Situation could be worse when some of the attributes may be of type CLOBs or BLOBs.

To avoid fault-in you can look up for such cases and add such attributes to your VO. This way, while executing the VO query for the first time it will automatically populate such attributes as well in the entity instances.

Another way is slicing your entity object into multiple entity objects and creating composite VOs. For example say you have a Emp table with 30 columns some of being CLOB and BLOB types or very less used. So, you can create two Entity Objects one with mostly used columns and another with rest of the attributes. Depending upon your business requirements you can create VOs either on just one of the two EOs or a composite VO based on both the EOs.


Friday, September 4, 2009

Fine tuning your Application Module in ADF

A lot of performance problems occurs because we leave the stuff as soon as it starts working as per the requirement.

We simply do not care at the performance issues it might create later in system testing or in production environment with real life load. I am not a guru of performance tuning but here is a little I learned from my experience:

1. Carefully investigate each and every instance you added in the Application module of your view objects. Go to the tunning tab and there set the batch size equals to 1 more than the expected number of rows the VO is expected to get from DB in most of the cases. This will save un-necessary db trips. So, say a VO instance is supposed to retrieve 20 rows from db then change the batch size to 21. By default it is 1.

2. Iterating over View objects is fairly easy and we easily get into the habit of copy paste the code to iterate over the View object to look for some particular row. Avoid that. Where ever possible have a view criteria with bind variables and use it in your code to fetch the desired row.

3. One of the most neglected area is executables sometimes left in pageDefinition files and un-used. During development we try various options when something does not work and forget to remove the dead code. So, those executables run at the page load time automatically and slow down the page load time even it does not have any other side-effects on the functionality of your app. So, remember to analyze bindings and executable in your pageDef and cleanup if needed.