Skip to main content

Why validation errors are not displayed in the UI when thrown from an application module method bound to a button?

Recently I came across an interesting issue reported related to validation error display. In short, the validation errors associated with an entity object is not displayed in the UI when thrown from an application module method which gets invoked when user clicks on a button. This post discusses the root cause for this issue and a possible work around solution for the same.

Before jumping into the topic, a bit of theory. The data validation is very essential for any business application. When user finishes a transaction, the application needs to validate all modified things before storing to data store. It would be ideal if the application can validate all dirty data in one go and show all associated errors in one shot, rather one by one. Oracle ADF BC has such support for validating all modified rows and attributes during a post back from the client and bundle all errors for display them in UI in one go. This is known as bundled exception mode. Take a look at the topic Understanding Bundled Exception Mode the Fusion Developers Guide to learn more. Now, straight to the issue.  Consider a scenario where you have an application module method which updates bunch of rows when user clicks a button EL wired to this method. Though all attribute level validation happens, you do not see error on the UI. Why? Here is the details:

 The bundled exception mode is true ADF BC by default. As we discussed a while back, this mode tells framework bundle all errors(not to throw immediately) till framework finishes validating all dirty rows. So these deferred(bundled) validation exceptions will be thrown tot he caller when run time calls validate() on DBTransaction object or individually on  view rows backed up by the entity object(s). In normal flow, framework calls validate on DBTransaction object at the end of  'validate model update' phase, which causes to throw all  the bundled exceptions back to the client. All works well here. However,  if you have some data manipulation logic in  your business method, then due to the bundled exception mode, errors wont be thrown to the client by default. Note that, the business method invocation happens as part of 'invoke application' phase (i.e after  'validate model update' phase during which framework take care of throwing bundled validation errors), so framework can't do much here. In such cases you may want to  call DBTransaction::validate(); once you finished manipulating all rows and before saving changes to database.  So the usage pattern for such use case is:
 

//A method defined in AM exposed for use by Client
 public void someBusinessMethodinAM(){
 
/** The following line throws validation exception as 
* DeprtamnetName has validation rule defined for not allowing
* special chars 
*/
     getDeptVO1().getCurrentRow().setAttribute("DeprtamnetName","@@#@#@@#%#@%");
     /**the following line throws validation error */      
      getEmpVO1().getCurrentRow().setAttribute("Email","xxx" );
 
/**Now to report all the bundled errors back to the caller, 
* add the following once you finish updating all rows
*/
     this.getDBTransaction().validate(); 
  //Other post validation operations go here...
}

Comments

Ramesh Pinjala said…
So in the case that you explained the validations are the ones that you define for the entity.

Now, lets says say that I want to validate this on entity based view-object with some other data I might do some 3 to 4 data integrity checks and I want to collect and these error messages and raise then as one JBoException. We had something like this in EBS OAF code line but not in Fusion Applications code line (or if there is a way to do it similarly in Fusion ) .

Popular posts from this blog

Happy New Year 2018 !

We can't go back and change the beginning, but we always can start where we are and change the ending. Believe in yourself and you will be unstoppable!

Wishing you and your family a very happy new year 2018 !!!

How to set Bind Variable Values at runtime ?

In this post I'm sharing a couple of approaches for programmatically setting bind variables values at run time. This post is an attempt to explain 'When to use what ?'[ In case if you are familiar with 'Bind Variables' in ADF BC, please refer Section 5.10, Working with Bind Variables in Fusion Developer's Guide ]

1. Set the Bind Variable value using RowSet::setNamedWhereClauseParam(...)

You can use use the setNamedWhereClauseParam(...) method on the ViewObject interface (which extends oracle.jbo.RowSet) to set the value for bind variables. Please note this sets the value on default RowSet. In other words, this doesn't have any effect on the secondary RowSets that you/system generates.
ViewObject vo = am.findViewObject("EmployeesView1"); vo.setNamedWhereClauseParam("bindVarDeptId", new Number(10)); vo.executeQuery();
2. Set the Bind Variable value using ViewObject's VariableValueManager::setVariableValue(...)

VariableValueManager Ma…