Overview

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

Jerry W. Walker

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

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:

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

And in Session:

  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:

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

Changing an EO after Validation

Question: I would like to make a change to an EO after it has validated but before it has saved to the graph/DB. Is this possible?

Chuck Hill

You don't want to do this, you should not want to do this, and the frameworks will fight you tooth and nail if you try. validateForSave is the gatekeeper for the object store. Its job is to ensure that nothing gets saved unless it has validated it. Modifying the object graph after validateForSave() finished would violate its very reason for existence.

As I see it, you have three options:

  1. Do it in the component
  2. Do it in the EO
  3. Do it in another object

I agree that the component might not be the place to do this and I also don't like to have my EOs call saveChanges(). You might want to think of the third option, having some sort of ShiftManager object that is responsible for overseeing the closing and opening of shifts. It can provide information to the page on what is valid and what options there are and it can handle the two phase save.

Before I did that, I would consider some other options. Here are some ideas that might spark some of your own:

public void close() throws ValidationException {
  validateForSave();
  cashBox().resetBalance();
}

and in your component

try {
  shift().close();
  ec().saveChanges();
} catch (ValidationException v) {
  // do the right thing
} catch (EOGeneralAdaptorException e) {
    // do the right thing
}