Validation Rules

Overview

Validation rules are domain-level rules executed on dirty domain objects prior to changes being sent to the database.

Implementation

Each domain object has a List<ValidationRule> rules that can be added or removed to as needed.

Code generation automatically adds some basic validation rules:

    public abstract class ChildCodegen ... {
        ...
        private void addExtraRules() {
            this.addRule(new NotNull<Child>(Shims.name));
            this.addRule(new MaxLength<Child>(Shims.name, 100));
        }
        ...
    }

But custom/business validation rules are simple to add, either as one-off inner classes:

    public class ValidationAFoo {
        public ValidationAFoo() {
            this.addExtraRules();
        }

        private void addExtraRules() {
            this.addRule(new Rule<ValidationAFoo>() {
                public void validate(ValidationErrors errors, ValidationAFoo foo) {
                    if ("bar".equals(foo.getName())) {
                        errors.addPropertyError(foo, "name", "must not be bar");
                    }
                    if ("baz".equals(foo.getName())) {
                        errors.addObjectError(foo, "is all messed up");
                    }
                }
            });
        }
    }

Or as higher-level, reusable rule, e.g.:

    private void addExtraRules() {
        this.addRule(new MustNotOverlap(Shims.children, ChildCodegen.Shims.begin, ChildCodegen.Shims.end)); // I think
    }

(Note: This example was used on a previous-generation Joist-like framework to ensure that parent entities with collections of time-based entries could validate that none of the children overlapped each other and not copy/paste the boilerplate overlap code into each parent entity.)

Notes

Validation rules might eventually use bindgen-generated bindings as bindings are stateful and so can navigate object graphs while shims are stateless and can only access single-level properties.