Sunday, April 26, 2009

When building large applications with Oracle ADF, you can consider to use inheritance in Oracle ADF BC layer. This can reduce Model complexity in terms of size and relationship. I will split inheritance topic into two parts - today I will describe inheritance with ADF BC Entities, and in my next post with ADF BC View Objects. I recommend to read Oracle ADF Developer guide related topic - 34.7 Using Inheritance in Your Business Domain Layer. In ADF BC you can implement inheritance layer for Entities and create View Objects with polymorphic Entity usages. This means Oracle ADF supports abstraction on both - components and data.

You can download sample application - ADFBCInheritance.zip where I have implemented inheritance between Entities and created View Object based on polymorphic Entity usage.

I have generated Countries Entity in order to use it as Base Entity in an inheritance hierarchy:

Four Entities - CountriesAfrica, CountriesAmerica, CountriesAsia and CountriesEurope are created as Subtype Entities from Countries Entity in inheritance hierarchy.

While creating Base Entity, I have declared discriminator attribute - RegionId. This attribute will allow us to perform polymorphic queries:

I have left discriminator value as empty by default, this means if View Object will not include any subtype, empty rowset will be returned:

Subtype Entities are created by extending Base Entity and overriding its attributes:

In Subtype Entity we need to set corresponding value for overriden discriminator attribute - RegionId:

For example, in CountriesAfrica Entity I have set this attribute discriminator value to 4:

In CountriesAmerica, CountriesAsia and CountriesEurope it is set to 3, 2 and 1 accordingly. Of course, there is no point to create inheritance hierarchy just for fun, in most of the cases its useful to have it when implementing different validation rules for example. In my sample, I have implemented different validation rules for transient Profit attribute. In CountriesAfrica Entity validation rule is implemented as range between 100 and 1000:

In CountriesAsia Entity, with discriminator value set to 2:

Same type validation rule is implemented with different constraints set to 300 and 1200:

Finally, when View Object is created based on Base Entity - Countries:

You need to include Subtypes of Base Entity you wish to use in your View Object. If you will not include any of Subtypes, View Object will return empty rowset (remember we have set empty default value for discriminator in Base Entity). In my sample, View Object will work with all four Subtypes, so I'm declaring this:

Even my View Object is based on all four Subtypes, I will want to limit rows to expected Enity Subtypes. We can do this, simply by adding discriminator into WHERE clause and declaring Bind Variable, however I have noticed if to implement it in such way - View Accessors from any Detail View Objects will not work. However, everything works fine, if to declare and use View Criteria:

This View Criteria is really simple, it just includes discriminator attribute filtering:

At this point, inheritance in ADF BC Entities is finished. Let's add some more complexity and define association relationship. I will define it between Countries entity with discriminator attribute and Locations:

Based on this association its possible to define Master-Detail relationship through View Link:

Its cool that, you can use Detail View Object - Locations in relationship with Master View Object - Countries just in standard way, even we know that Countries is based on Entity Subtypes. In order to test and prove this, I have created transient attribute in Locations View Object - CountryName. This attribute gets value through accessor from its Master - Countries:

We have following Master-Detail relationship exposed to View-Controller layer:

In View-Controller I have created navigation flow to pass discriminator value into Bounded ADF Task Flow through a call:

In Bounded ADF Task Flow I'm doing ExecuteWithParams in order to set Bind Variable value and opening main page with already filtered values by provided discriminator:

Tuesday, April 14, 2009

In February, I was blogging about - Workaround for LOV on Primary Key Attribute. Provided workaround and sample application was working nicely, but it was working only in edit mode, when already existing row was updated. There was a need in my project, to update previously developed workaround in order to have working functionality when current row is in create mode.

I'm posting updated sample application, you can download it - LOVPrimaryKeyCreate.zip. This sample implements workaround for LOV on Primary Key for both cases - edit and create modes. Most probably you will face described problem in current JDeveloper/ADF builds (5188 and 5205).

One specific with create mode is that Primary Key usually have database constraint - Mandatory:

This means, on runtime - when user will try to create new row and will do commit - validation error will be generated for LOV attribute. Its because value from dummy attribute will not be copied into real attribute, validation will fire first for empty real attribute value:

Its possible to solve this problem, by simply updating previously described workaround. Idea is to initialize real key attribute with some dummy value when create is invoked. In my sample, I'm using main key negative value retrieved from DBSequence. I'm assigning this value in overriden create method:

This means, validation will not be fired anymore and dummy value will be changed with a real one in doDML() method (same as in original version of workaround):

Thursday, April 9, 2009

In my previous post - WebLogic Load Balancing for Oracle ADF Applications, I have described how to setup cluster environment with a set of WebLogic Managed Servers together with separate WebLogic domain for Load-Balancing. Today I will describe, how to enable In-Memory replication in cluster environment.

Load-Balancing allows to distribute user sessions across cluster elements, based on current server load. However, if one of Managed Servers from cluster will go down, all the sessions on this server will be destroyed and users will loose their work. In order to avoid this, WebLogic server allows to enable replication between Managed Servers in cluster. In this blog I'm describing In-Memory HTTP replication.

You can enable session replication, basically by adding one parameter into weblogic.xml file. You should edit weblogic.xml available in your Oracle ADF application, if you don't have this file - create it in WEB-INF folder:

Load-Balancing domain have redirected to a second Managed Server, I have pressed Save button on application page couple of times, you can see it from the server log:

I have killed second Managed Server:

I didn't closed my browser and have pressed Save button again - without replication I would get server error, however now my session is successfully transferred to the next available Managed Server from cluster environment - its third server:

You can see from the log - Save operation was successfully done. User didn't lost his session and can continue work:

Sunday, April 5, 2009

Why I like WebLogic server, is because it works as it should work - as it is described in documentation. I'm enjoying to configure WebLogic environment and with my today post I want to share how to setup Load Balancing for Oracle ADF applications using WebLogic 10.3.

Before configuring Load Balancing, we will need to setup WebLogic cluster. Sample Oracle ADF application will be deployed on WebLogic cluster, Load Balancing domain will distribute user requests between cluster members (WebLogic domains).

1. WebLogic Cluster Setup

You can setup WebLogic cluster on your machine very easily, just use standard installation wizard and choose customized installation be selecting 'Yes' and pressing Next button:

Change port number for Administration Server from default to unique in your environment, I will change it to 7002:

Configure cluster by accepting defaults, we will change later Multicast to Unicast:

Simply assign all three defined Managed Servers to configured Cluster:

Configure Machine - I will use one physical machine:

Assign all servers to defined machine:

And finally, provide name for cluster domain and specify domain location:

At this point, WebLogic Cluster is installed and ready to be used. Ensure that Admin Server is running, Open Web Console for Admin Server and change Multicast messaging type to Unicast:

You can start each of three Managed Servers in defined Cluster using startManagedWebLogic managedServerName command from console. In Admin Server Web Console you can access Cluster information tab, all three Managed Servers should be running:

Finally, define JDBC Data Source and deploy it on Cluster:

2. Load Balancing Domain Setup

I will describe how to setup Load Balancing with Proxy Plug-in. As proxy, I will use separate WebLogic domain. This domain can be installed as standard domain, without any customizations:

Specify domain name and location:

I have installed Proxy domain for Load Balancing on default, 7001 port - later I will access Oracle ADF application deployed on Cluster environment through 7001 port:

Before you will start to use WebLogic domain as Proxy Plug-in for Load Balancing, you will need to set up HttpClusterServlet. Consult documentation for additional information - Configuring Proxy Plug-Ins. I have used sample web.xml available in documentation, just changed WebLogicCluster parameter value to:

localhost:7003|localhost:7004|localhost:7005

As you can see, I have specified addresses of three Managed Servers from my Cluster. I have packed web.xml along with weblogic.xml into load-balancer.war and have deployed this war file on WebLogic Load Balancing domain:

Load Balancing setup is done.

3. Load Balancing Test

In this section I will describe how to test defined Load Balancing domain and will show how user requests will be distributed across cluster.

First, in cluster environment, from Admin server I will deploy Oracle ADF application. Application will be deployed on cluster:

When application will be deployed and user will access it using (note: I'm using Load Balancing domain port number):

http://localhost:7001/cluster_test/faces/main

One of Managed Servers from Cluster environment will response, in my case it was second server:

Oracle ADF application is opened:

I have opened second session, by pointing to the same 7001 port and it was handled by third Managed Server:

Third session on 7001 Load Balancing port, was handled by first Managed Server:

When I have opened fourth session, it was handled by second Managed Server - second circle have started, its because Cluster is configured with round-robin algorithm. Second Managed Server have responded to fourth session request: