Posts

Showing posts from February, 2011

Yet another reason for "JBO-25014: Another user has changed the row with primary key oracle.jbo.Key"

I've discussed one possible (tricky) reason for JBO-25014 error in one of my previous post - 'What you may need to know about Nested Application Module' . Recently I noticed yet another interesting reason for the above said JBO-25014 error. Let me summarize the same for the benefit of the ADF community.

Use case

This use case has two view objects - SimpleEmployeeViewObject and DetailedEmployeeViewObject, both are based on the same entity object - EmployeeEntityObject. A specific business functionality is implemented using the above ViewObjects as listed below.

1. SimpleEmployeeViewObject queries the DB by calling SimpleEmployeeViewObject.executeQuery(). The code doesn't fetch any records at this stage(I meant that, this code just got the executeQuery call, no iteration logic). However this call results in the creation of result set/cursor, and leaves it opened.

2. Then, DetailedEmployeeViewObject queries by calling DetailedEmployeeViewObject.executeQuery(). Here the cod…

<af:setPropertyListener> not working on <af:popup> with childCreation="deferred" !

You should be careful while using <af:setPropertyListener> on <af:popup>. There is a known limitation when you use <af:setPropertyListener> with 'popupFetch' type to initialize the properties/parameters for a <af:popup>. The relevant jsf snippet may look like as shown in the following diagram.

<af:popup id="p1" contentDelivery="lazyUncached" childCreation="deferred"> <af:setPropertyListener from="'check'" to="#{requestScope.params}" type="popupFetch"/> <af:dialog id="d2" title="Check"> <af:outputText value="Param from the caller: #{requestScope.params}" id="ot2"/> </af:dialog> </af:popup>
When you run this page, you may notice that the setPropertyListener with a popupFetch type is not getting called for the first time, and the same works without issues from next …

Overriding Control Hints of a View Object on the fly

I recently came across a use case where the requirement was to fetch Attribute Hints(display width, label etc.) for a View Object(and Entity Object) on the fly from an external system. Let me share a simple possible solution for this specific use case.

A glance at the implementation

The idea is to override ViewRowImpl::createViewRowAttrHints(AttributeDefImpl attrDef) to return a custom implementation of ViewRowAttrHintsImpl class. The same concept has been discussed in one of my previous post sometime back - Decorate UI with view row Attribute's User Interface hints. Please note that, this is the place( custom ViewRowAttrHintsImpl class - LazyViewRowAttrHintsImpl) where we are adding the hook to retrieve the Attribute Hints from third party service.

@Override protected ViewRowAttrHintsImpl createViewRowAttrHints(AttributeDefImpl attrDef) { return new LazyViewRowAttrHintsImpl(attrDef, this); }
The constructor of LazyViewRowAttrHintsImpl may look like as shown in the following code…

Customizing the width of a UI control using contentStyle attribute

You can use contentStyle attribute to override the default width of specific types of UI controls. This property is applicable for single select and multiple select controls( af:selectOneChoice, af:selectManyShuttle, af:selectBooleanRadio etc.) and input controls( af:inputText, af:inputRangeSlider, af:inputListOfValues,af:richTextEditor etc. ).

<af:selectOneChoice contentStyle="width:200px" label="Select an Item:" id="soc1">
From Web User Interface Developer's Guide...
If the field is wider than the space allocated, the browser will not truncate the field but instead will take space from the label columns. This potentially could cause the labels to wrap more than you would like. In this case, you may want to consider reducing the width of the field contents (for example, use a smaller contentStyle width on an inputText component).

However, you should be cautious while using 'contentStyle' to override the default width of the controls, …

Creating Custom History Types

Image
While dealing with business data, 'history' has its own role to play. The 'history' here means, data specific to a point in time. Most of the enterprise application may capture audit information when the user commits a business transaction. These audit data may includes previous value of some sensitive attributes, user who modified the data, modified date etc. ADF BC framework ships with a number of history types, but you can also create your own on need basis.

Life cycle of a 'history type' attribute

Question here is, who does update these attributes (and when)? Well, this job is done by the ADF BC run time at prepareForDML phase of a transaction post cycle. When you commit/post a transaction, Transaction Manager would take each entity object through a transaction post cycle as shown in the following diagram.


prepareForDML - Issues pre-doDML ntofication for all entities, this is used to assign history values before an entity row is saved. Run time uses attri…

Disclaimer

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