Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Overview

http://developer.apple.com/documentationlegacy/mac/library/#documentation/WebObjects/Enterprise_Objects/BusinessLogic/chapter_4_section_4BusinessLogic.html

mmalcolm's StepWise article entitled "Data validation with WebObjects 5": http://www.stepwise.com/Articles/Technical/2001-06-13.01.html

Jerry W. Walker

WO and EOF have an incredible array of validation mechanisms. Here are some notes you might find helpful:

  • User interface:
    • prevent/discourage user from entering inappropriate data
  • Formatters:
    • formatting
      • Only accepts data with valid format
    • type coercion
      • bad type raises exception
    • simple validation
      • raises exception and ignores value
      • must be different from current value or not assigned
      • WOComponent's validationFailedWithException(Throwable t, Object value, String keyPath)
        • Called when an Enterprise Object or formatter failed validation during an assignment.
        • The default implementation ignores the error.
        • Subclassers can override to resolve the error.
  • Model
    • attribute constraints
      • checks for:
        • allows null
        • string length
        • numeric precision
        • relationship integrity
      • checks these before going to DB
    • relationship integrity constraints
      • optionality
        • for both to-one & to-many
      • delete rule
        • if source deleted, then what
      • ownership, owned object is:
        • deleted if relationship broken
        • created if relationship added
      • delete rules (if user tries to delete relationship source):
        • cascade - delete all destination objects too
        • nullify - nullify back references
        • deny - prohibit delete if there are destination objects
        • nothing - delete and ignore destination objects
  • EO
    • property-level (or key-level) validation
      • called when a value changes
      • default methods in superclass check model based constraints
      • can be overridden for custom validation
      • called BEFORE EO's properties have changed
      • validation methods throw exception on failure
        • validateValueForKey("weight") triggers: public <type> validateWeight(Object newWeight) throws NSValidation.ValidationException {
    • object-level validation
      • called when saving insert/delete/update changes
        • public void validateForInsert() throws NSValidation.ValidationException
        • public void validateForUpdate() throws NSValidation.ValidationException
        • public void validateForDelete() throws NSValidation.ValidationException
      • all above in superclass by default call:
        • public void validateForSave() throws NSValidation.ValidationException
      • super's implementation calls key-level validation
      • called AFTER EO's properties have changed
    • validation performed when:
      • form values are pushed into EO attributes through bindings
      • saving changes in the editing context
      • called programmatically

Checking for validation problems before calling saveChanges

You might want to display validation problems/exceptions before you try to insert/update an EO by calling saveChanges. To get the exceptions, in your component, override validationFailedWithException, with something like this:

Code Block

  public void validationFailedWithException(Throwable exception, Object value, String keyPath) {
    super.validationFailedWithException(exception, value, keyPath);
    session().addError(exception.getMessage());
  }

And in Session:

Code Block

  private NSMutableArray<String> _errors;

  public NSArray<String> errors() {
    return _errors.immutableClone();
  }
  
  public void setErrors(NSArray<String> errors) {
    this._errors = errors.mutableClone();
  }
  
  public void addError(String error) {
    _errors.addObject(error);
  }
  
  public boolean haveErrors() {
    return ((_errors != null) && (_errors.count() > 0))? true: false;
  }
  
  @Override
  public void awake() {
    super.awake();
    _errors = new NSMutableArray<String>();
  }

And before calling saveChanges on the editing context:

Code Block

if (session().haveErrors()) {
  return null;
}
...
ec.saveChanges();

Changing an EO after Validation

...