Tuesday, November 27, 2012

ADF_FACES-60003:Component with ID: not registered for Active Data

Came across this error recently in version 11.1.1.4.0. 

The error was reproduceable on screens where file uploads, downloads and deletes were occurring (via UCM) and components on the screen needed to be refreshed (partial triggers or navigation) afterwards.  These actions were being applied on af:panelCollection and subsequent af:table rows.

I tried this solution but it did not work in my case. My colleague's old blog post relating to data exports was also not the solution I was looking for.

After trying several things, the solution for me was changing the af:table ContentDeilvery property from immediate to the <default> (whenAvailable).

This seems like a bug in this version but I hope this simple change will save somebody else hours of debugging.

Monday, February 27, 2012

List Of Values always returning 1st Row

On version 11.1.1.4.0 (very possibly on later versions too).

Old issue that I recently encountered again, thought it worth listing for reference purposes.

Problem: No matter which row the user selects on the List of Values (LOV) component, the LOV always returns the 1st row of LOV collection to the input field associated to it.

Solution: Check LOV View Object's attributes, you will find that no attribute(s) have been identified as Key attributes.

Explanation: Once the row in the LOV is selected, ADF does a getKey on the row to determine the Key which uniquely identifies the row in the View Object (which returns null or Empty Key if no Key is specified).  After that it does a findByKey on the LOV View Object to get the values to be returned to the af:inputTextListOfValues field.  Because the key is null, the findByKey does not know which View Object row to retrieve and at this point it just returns the first row of the LOV View Object rowset.

Specify your Key attributes, even if you have to make up a composite unique key on the VO, and your problem will be resolved.

Uploading Files

Quick note regarding the use of af:inputFile component.  It's not something I use too often but when I do there is a step I always forget:

In the parent af:form component set the usesUpload property to true. This is nothing new and is in the documentation...but I always forget until I look at the docs again.

Note: You can only use 1 af:form on any given page, so set the property on the af:form component in your housing JSPX page if you are using fragments.

Wednesday, February 15, 2012

Validate whole numbers

Simple way to do this is to add an af:validateRegExp to your af:inputText field, e.g.:
<af:validateRegExp pattern="^[1-9]+[0-9]*$"
                               messageDetailNoMatch="Value must be specified in whole number format."/>


NOTE:  when you drag n drop a number field from your view object ont a page as an af:inputText component, it adds an af:convertNumber by default.  In this case your RegExp validator will not fire as the number conversion will happen first.  This is fine to catch Alphabetic characters, but fractions will simply be rounded as per the rules specified in the af:convertNumber and no message will be raised for the user.  So if you want to validate via RegExp, delete the af:convertNumber .

A further addition to this post.  If the number field is based on a database Number column, you might want to consider specifying a precision on the column in the database and then synchronize those changes to your Entity Object in ADF.  You will then see a new Database Constraint validation added for the attribute in your Entity Object (consider adding a user friendly error message to the validation at this point).

Alternatively, if the inputText component is bound to a View Object or Entity Object, and no precision is specified on the database, you could add a RegExp validation to the attribute on the model layer.

Wednesday, January 11, 2012

Overriding prepareSession on Application Modules


Had a case where an overridden prepareSession method in an Application Module Implementation class was not firing each time a new database session was acquired by the Application Module.

The method was only firing the first time the Application Module was instantiated, however the prepareSession method in the super was firing each time as expected.  As a result, database session data which was being set in the prepareSession method was not always available on the database session.

After some time I realised that the wrong prepareSession method was overridden.  There are 2 available in for overriding, the difference being the parameters - Session vs SessionData.  Check carefully when choosing which to override, this could cause unexpected behaviour and be time consuming to debug when the wrong one is used:

Fig. 1

To do something for each database session retrieved by the Application Module, you should only ever use the one highlighted in Fig. 1.  There is not much oracle documentation available on the differences between the two.  Even in Chapter 9.11.3 of the Developer Guide they just refer to the method as prepareSession() in the text.  In the example code though, you will notice that they use prepareSession(Session session).

Also, if you check the javadocs for ApplicationModuleImpl, you will see it is suggested to never use prepareSession(SessionData sessionData) in your application:



Friday, June 24, 2011

Unable to create an instance of the Java Virtual Machine

Get the following error at startup when trying to run Jdeveloper 11.1.2.0.0 on a Window 7 Home Premium PC:


Unable to create an instance of the Java Virtual Machine 
Located at path:
C:\Oracle\Middleware\jdk160_24\jre\bin\client\jvm.dll

Solution:

  • Locate file jdev.conf (e.g.: C:\Oracle\Middleware\jdeveloper\jdev\bin) and edit.
  • Locate line AddVMOption  -XX:MaxPermSize=256M
  • Add line AddVMOption -Xmx512M
  • Save and Start MaxPermSize again.