Title: DataObject Validation

DataObject implements a set of methods to validate its state. DataContext calls these methods before performing a commit. If validation fails, the commit is aborted with ValidationException. There are a few clear benefits of validating DataObjects at the application level before committing them to the database:

Validation API

Each DataObject participating in commit operation (i.e. those in state NEW, DELETED or MODIFIED , in other words "non-committed") will be validated by DataContext's ObjectStore during commit processing. Depending on the non-committed object state, ObjectStore calls one of the methods described below (description of method behavior is provided for CayenneDataObject implementation):

Custom validation method implementation would normally append any failures to the provided ValidationResult instance. After validating all non-committed objects, DataContext (or rather its ObjectStore) will check if the ValidationResult is not empty, and throw an exception if there is at least one failure. Typical custom validation method would look like that:

public class Painting extends _Painting {
   ...
   protected void validateForSave(ValidationResult validationResult) {
      super.validateForSave(validationResult);
     
      // check business rules
      if(getEstimatedPrice().doubleValue() <= 0.0) {
         validationResult.addFailure(
                this, // source object of the failure
                Painting.ESTIMATED_PRICE_PROPERTY, // failed property name
                "Painting price must be greater than zero.")); // error message  
      }
   }
   ...
}

Validation Methods with Side Effects

Often validation methods are implemented to modify an object being validated and/or other persistent objects. Cayenne supports such behavior, however a few things should be taken into consideration:

Turning Validation On/Off

Whether DataContext performs validation at all depends on the value of its property validatingObjectsOnCommit. Calling isValidatingObjectsOnCommit() returns currently configured value. Default value (usually "true") is propagated from the parent DataDomain when DataContext is created. This default value can be configured using CayenneModeler as described in Configuring Object Validation section.