Sunday, October 9, 2011

Validating The Entity Collection When You Commit the Transaction

In this post I'm sharing an approach to trigger the validation once for the entire entity collection when you commit the transaction. Steps :
  • Define a method validator for the entity object. In the Add Validation Rule dialog, select the Validation Execution tab, and choose Defer the execution to Transaction Level 
  • Implement the validation method in your entity implementation class. An example is shown below:
    /**
     * Validation method for Departments.
     */
    public boolean validateDepartments(ArrayList ctxList) {

        Iterator iter = ctxList.iterator();
        while (iter.hasNext()) {
            JboValidatorContext entValContext = (JboValidatorContext)iter.next();
            DepartmentsImpl deptEO = (DepartmentsImpl)entValContext.getSource();
            if (deptEO.getDepartmentName() == null) {
                // if Dept is null, throw error- this is just an example to illustrate the usage of this method
                return false;
            }
        }

        return true;
    }
  • Ope the page which uses the above entity, keep SkipValidation="skipDataControls" in the page definition file
Download

You can download the sample workspace from here. [Runs with Oracle JDeveloper 11.1.2.1.0 (11g R2PS1) + HR Schema]

How to run this sample?

1. Run test.jsf
2. Nullify Department name field in multiple rows and click Commit. Validation gets triggered only once for the entire collection when you press commit.


Learn More ...

There are a lot more points like this. If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html

8 comments:

Peter O'Brien said...

Does the use of SkipValidation="skipDataControls" mean that all entity level validators are deferred or just those that have transactionlevel = true?

Jobinesh said...

Peter,
I can see SkipValidation="skipDataControls" skips both EO levl an transaction level validations in my sample. Waiting for dev team's response on this . Will keep you posted.

Jobinesh said...

This is a bug, please contact Oracle support if you are facing this issue in your App - this line is not for you Peter :-)

kumar said...

Hi Jobinesh,

1. From the transaction level validation method I have to show different validation error messages. So I cannot stick to the same error message I have defined while creating the validation in the business rules section of entity. Is this possible? Right now I have approached this in the following way. Can you tell me if this is the right way?

ResourceBundleDef resourceBundle = getResourceBundleDef();
if (somecondition){
throw new ValidationException(resourceBundle, ERROR_MESSAGE_KEY, new Object[] {parameters});
}
else if (somecondition2){
throw new ValidationException(resourceBundle, ERROR_MESSAGE_KEY2, new Object[]{parameters});
}

2. Once the error is raised, I am not able to do any action on the screen(no selection) as the same error message is kept popping up and being added to the list of errors.

Jobinesh said...

Ch 11 in my book (oracle adf real world developer's guide) has samples on wrapping multiple validations errors in single exception. The sample is too big to post here. In case you don't have a copy drop your email id here, I'll send u the code snippet

kumar said...

Thanks Jobinesh.

Regarding the second issue, can you tell me how to fix it? Because, after validation errors are shown, nothing is allowed on screen, not even I can correct the error and provide valid value.

Jobinesh said...

Same as I mentioned earlier...Try wrapping them in single exception and throw the wrapped exception manually

JustMe said...

Hi Jobinesh,

I have implemented the solution you describe. The first time the validation executes successfully and works as expected. If I try and commit the data again, the validation does not get executed and the data is committed to the database. Is there something that I am missing?

Regards

Leon