Thursday, August 11, 2011

Validation horrors! I mean errors!

Problem: Client needs to collect all validation errors from business layer before request completes.

Solution: Pass an error collection as a return object from service methods.

Problem: Error collection prevents more logical objects from being returned, as an error holds no true value in the domain context.

Solution: Create error collection during the client request that is passed as a parameter to service methods.

Problem: Client has to instantiate Errors collection. Also, the client is not forced to handle any broken business rules that may have occurred. Thus rendering validation efforts futile.

Final Solution: Return Errors only from "validate" methods. Have your service methods throw a runtime exception, of type ValidationException. This ValidationException should persist an immutable collection of errors.

Caveat: Every service call will need to individually catch validation exceptions.


class Errors implements iterable {
...

public void evaluate() {
if(this.hasErrors)
throw ValidationException(this);
}
}

class StuffService {
...

Stuff findStuff(StuffCriteria criteria) {
Errors errors = stuffValidator.validate(criteria);

errors.evaluate(); //throws ValidationException if errors present

return stuffDao.findStuff(criteria);
}
}

class StuffClientSearchForm {
...

onSubmit() {
...

try{
stuff1 = stuffService.findStuff(criteria1);
} catch (ValidationException ve) {
for(Error error in ve.getErrors())
addClientError(error.getMessage);
}

try{
stuff2 = stuffService.findStuff(criteria2);
} catch (ValidationException ve) {
for(Error error in ve.getErrors())
addClientError(error.getMessage);
}
...
}
}

Monday, May 9, 2011

Best data type for PRICE!

In attempting to persist U.S. currency formatted values from an H2 database via Hibernate and JPA, I've found using a primitive type of double, a variable precision and a scale of 2 finally gave me what I wanted.

BigDecimal result = new BigDecimal(129.99, 7).setScale(2);

BigDecimal(double value, int precision)