gravatar

Warning on unsaved changes

http://www.oracle.com/technology/products/adf/patterns/11.1.1.1.0/UnsavedDataWarning.html

gravatar

Storing non-serializable objects

In many cases there are requirements, where every user session needs a seperate object to be used throughout the session.
For example, let us take the example where there is requirement to access the SOA related data from the Application Module. To access the data from the SOA server, a connection has to be established to the SOA server and then appropriate data has to be queried. The same connection cannot be used by all users (or cannot be used in all user sessions). Every user session should have a seperate connection, so that when queries are executed, only the data related to the user are fetched. So for every user session, a seperate connection object is required.

So how can we make evey user have a seperate unserializable object?

The simplest way to achieve this is to re-create the object every time it is required. But in many cases, recreating such objects can have serious performance implications. So what else can be done?

The only other thing that can be done is to minimize the number of times the object is re-created.
This can be achieved by storing the non-serializable objects in the session of the DB transaction associated to the Application module.

The following piece of code shows how to do that..

getDBTransaction().getSession().getUserData().put("key",non_serializable_obj_instance);

So the overall procedure should be as follows..

  • Check whether the require object is present in the user session
  • If the object is present , just it
  • If the object is not present, create an instance of the object. Put a reference of the object in the session and use the reference.
The session associated to the transaction, gets re-initialized whenever passivation/activation happens. So all the objects placed in the session will be gone after the passivation/activation cycle.

gravatar

Basic information about xsd's and namespace

An xsd file can refer to another xsd file in two ways..

  • using <import> tags
  • using <include> tags
The <import> tag has to be used, when an xsd wants to refer another xsd whose "targetNamespace" values is different.
The <include> tag has to be used, when the "targetNamespace" of the referred xsd is same as the "targetNamespace" of the referring xsd..
You cannot "import" an xsd whose "targetNamespace" is same as the "targeNamespace" of the referring xsd file...
Similarly, you cannot "include" an xsd whose "targetNamespace" is different from the "targetNamespace" of the referring xsd file.

gravatar

Populating Primary Key of Entities in 11g

Its a common requirement to populate the primary key of an entity automatically, as soon as an entity is created.

There are many ways to populate the primary key of an entity. There are programmatic ways to populate the primary key. Also there are ways to populate the primary keys based on a database sequence.

In 11g ADFbc can auto populate the primary key of an entity if the java type of the attribute is "java.lang.Long". This is done declaratively. Select the attribute whose value should be populated automatically. Then go to the property inspector. Expand the "Applications" tab and then change the drop down with the label "Application Unique ID" to "true".

That's it..

But for this to work properly, the database that is used for fetching the information should have a table with the name like "S_ROW_ID" and there are many other requirements..If you use the latest 11g database then there is nothing to worry about.

If this does'nt work for you and have to populate the attribute with a value of a DB sequence then do the following .

Select the attribute , whose value has to come from the DB sequence. Go to the property inspector. Expand the "Value" tab and select "Expression" as the "Default value type" radio button. In the "Default Value" input field, provide a groovy expression like "(new oracle.jbo.server.SequenceImpl("DB_Sequence_name",object.getDBTransaction())).getSequenceNumber()"

There are many other ways to populate the primary key. Look into the online documentation for this.

gravatar

Basics of AM pooling

Basically, every user request will be given an AM instance from the AM pool. Before the response for the user request is sent back to the client, the AM instance will be saved back to the AM pool. A user may not be given the AM instance which was given to him previously. This can happen, when all the free AM instances have been used up . Before giving an AM instance to a user, ADFbc checks if the AM instance has been serving the previous requests of the user. If not, the framework will passivate all the AM state and will re-intialize its state so that it can start serving the new user.

During this entire process, there are few hook points in the Application Module class where the developer can have custom logic to implement his requirements. The most important of these hook points is the method "prepareSession(Session sessionParam)".

This method will be called, in the following cases.

  • When there are free AM instances, and a user has sent a request for the first time.
  • When all the free AM instances are used up and one on the AM instances has to serve the request of a new user.

gravatar

Entity States (Entity Life cycle)



The above picture explains how an entity object moves from one state to another..

When an entity row is in memory, it has an entity state that reflects the logical state of the row. When an entity row is first created, its status is New. You can use the setNewRowState() method to mark the entity as being Initialized, which removes it from the transaction's list of pending changes until the user sets at least one of its attributes, at which time it returns to the New state. This allows you to create more than one initialized row and post only those that the user modifies.

The Unmodified state reflects an entity that has been retrieved from the database and has not yet been modified. It is also the state that a New or Modified entity transitions to after the transaction successfully commits. During the transaction in which it is pending to be deleted, an Unmodified entity row transitions to the Deleted state. Finally, if a row that was New and then was removed before the transaction commits, or Unmodified and then successfully deleted, the row transitions to the Dead state.

You can use the getEntityState() method to access the current state of an entity row in your business logic code.

If you use the postChanges() method to post pending changes without committing the transaction yet, the getPostState() method returns the entity's state from the point of view of it's being posted to the database or not. For example, a new entity row that has been inserted into the database due to your calling the postChanges()method programmatically — but which has not yet been committed — will have a different value for getPostState() and getEntityState(). The getPostState() method will reflect an "Unmodified" status since the new row has been posted, however the getEntityState() will still reflect that the entity is New in the current transaction.

gravatar

Does every master entity row has a seperate RowSet object

Yes every master entity row has a seperate RowSet object containing all its child rows...

Let us take the Department and Employee tables...Assume that the primary key of the department table is the "DepartmentName" and not the "DepartmentId"... Let us say that there is an association between the Department entity and the Employee entity based on the "DepartmentId" attribute, so that the Department entity is the master and the Employee entity is the child..

So for every department row, there should be a RowSet using which all the associated Employee's can be found...

Even if there are two deparment rows having the same "DepartmentId" values, each row will have a seperate RowSet object...but both the RowSet objects will be pointing to the same iterator...

So if multiple master rows have the same source attribute value , then ADF bc is clever enough to fetch all the rows from the middle tier instead of firing queries to the database to fetch the child rows...

This is true even if the association accessors are retained.

Does this mean anything?

This information is given just to explain that ADFbc is good at deciding when it has to go to database and whether it can fetch all the necessary information from the middle tier