This is the beginning of a set of Java 5 annotations for the Cayenne Object relational (ORM) framework. Currently only a validations package is supported.

The initial motivation came about from using the Tapestry Beanform component. Beanform will create a Tapestry/Html form for you at runtime including appropriate field types and validations dynamically based on a Bean passed to it. There are a lot of customisations that can be done. Powerful stuff, it can save a lot of time, effort, errors. There were annotations already available for other ORM's but I needed one for Cayenne.

What I've come up with so far to solve this:

  1. A modified Cayenne super-class Velocity template to generate Cayenne Annotations. Generates Required and Length annotations
  2. An annotations package based on OVal. includes Min, Max, Required, Past, Future, RegEx, Email, Length, Size, MinSize, MaxSize (those 3 for collections) and (for kicks) UpperCase and LowerCase.
  3. A Tapestry Beanform Cayenne integrator.


  • Download the latest Cayenne annotations from or check it out from SVN.
  • Integrate it into your project. If you are using Maven simply put this into your pom.xml:
  • Generate your Cayenne sub-classes using
    • The version 1.2 generator for your sub-classes
    • and for super-classes using the supplied template: superclass_annotations.vm

Basic Use with Beanform

Once setup all the user cares about then is practically very little. Beanform grabs the Cayenne generated annotation and generates the Tapestry validator for them.

Adding more validations

You can also add in annotations that can't be guessed from your data model into your subclass, just override the superclass eg:

    public String getEmail() {
       return super.getEmail;

Using OVal for validation

Next step is when we want to add a validation that none of the frameworks support (maybe you have a rich client etc), this is where OVal really comes into it, eg:

    Cayenne sub-class:
       // Must be uppercase and is required
       public String getUpperCaseField() {
          return  upperCaseField;

    Validation layer, eg Tapestry page class:
   Validator validator = new CayenneValidator();
    // collect the violated constraints
    List<ConstraintViolation> violations = validator.validate(myObjEntity);
    if (violations.size() > 0) // tell the user what is wrong from annotation generated message, required field must be upper case etc;