Tuesday, September 1, 2009

ADF: Transaction Level Validation

In ADF-BC4J, we can declaratively define validations. Validations can be at
1. Attribute Level
2. Entity Level
3. Transaction Level

In this post, we are going to see How to execute transaction level validation. As compared to entity level validation,which fires once for each entity, a transaction level validation is fired once for ALL entities.

Lets take a use case.
Say my rule is, There should be only one clerk per Dept.
Or
A customer can have multiple Address associated to it. but only one address can be primary address.

Such validation, should be at Transaction Level.

Lets say you are creating employees.
You add a employee "MARK" in dept 90, as "ST_CLERK"
As soon as row looses focus, or you create a new row, Entity level valdiations would fire.
Now add another employee "JOE" in dept 90, as "ST_CLERK", tab out. Again entity level validations would fire.

Now if you commit, Transaction level validation would fire. This gives us a chance to throw an error to user, that You cannot add more then One Clerk in a Dept.

If we had created this validation at Entity level instead, unnecessarily the validation would have fired twice.


Now lets look at the syntax of Transaction Level validation.

Following code is in EOImpl

public boolean validateSingleClerkinDept(ArrayList ctxList) {
System.out.println("in method validator");
int noOfClerks = 0;
boolean isValid = true;
for (int i = 0; i < ctxList.size(); i ) {
JboValidatorContext ctx = (JboValidatorContext)ctxList.get(i);
EmployeesEOImpl eorow = (EmployeesEOImpl)ctx.getSourceRow();
if(eorow.getJobId().equals("ST_CLERK")){
System.out.println("validating for " eorow.getFirstName());
RowSet rowset = eorow.getEmpVVO1();
ViewObject vo = rowset.getViewObject();
vo.setWhereClause("JOB_Id = :pJobId AND DEPARTMENT_ID = :pDeptId");
vo.defineNamedWhereClauseParam("pJobId", null, null);
vo.defineNamedWhereClauseParam("pDeptId", null, null);
vo.setNamedWhereClauseParam("pJobId", eorow.getJobId());
vo.setNamedWhereClauseParam("pDeptId", eorow.getDepartmentId());
rowset.getViewObject().setQueryMode(ViewObject.QUERY_MODE_SCAN_VIEW_ROWS |
ViewObject.QUERY_MODE_SCAN_DATABASE_TABLES |
ViewObject.QUERY_MODE_SCAN_ENTITY_ROWS);
rowset.executeQuery();
if (rowset.hasNext()) {
noOfClerks ;

}
if(noOfClerks > 1) {
isValid = false;
break;

}
}
}
return isValid;
}


We are all set with as per as back end is concerned.

Test from AM. Create "Mark " and "JOE" as above, and only when you commit you'll see the error message.

Notice that method validator is only called once, for Both new rows that were created.

No comments:

Post a Comment