wiki:MappingDecorator

Version 5 (modified by jvelde, 14 years ago) (diff)

--

Decorators for database mappers

You can customize the way entities are added, updated or removed by the database logic by adding decorator classes. Start by adding a decorator your your entity:

<entity name="Example" decorator="decorators.ExampleDecorator">

This will put a template decorator 'ExampleDecorator.java' in a package 'decorators' in your Java source folder. If you open this file, you will notice three functions:

public int add(List<E> entities)
public int update(List<E> entities)
public int remove(List<E> entities)

Each of these functions can be customized with new pre-, post- and database action behaviour, in a sequential layout:

// add your pre-processing here

// here we call the standard 'add'
int count = super.add(entities);

// add your post-processing here
// if you throw an exception the previous add will be rolled back

Example

For example, change the value of the field 'name' by turning it into uppercase before adding:

public int add(List<E> entities) throws DatabaseException{
    try{
        for (Entity e : entities){
            e.set("name", e.get("name").toString().toUpperCase());
        }
    } catch (ParseException pe) {
        throw new DatabaseException(pe);
    }
    int count = super.add(entities);
    return count;
}

Remember the functions get a list of entities which can be adressed in the most low-level form (org.molgenis.util.Entity) as shown in the example. However, usually you want to use the generated class for this decorator to use its field functions, so the previous example becomes:

for (Example e : entities){
    e.setName(e.getName().toUpperCase());
}

Which makes more sense!

If you have multiple pre- and post dependancies, your decorator will become much more tricky and the "pre -> action -> post" order will become blurred. These decorators can become very powerful and save you much work in other places, though.

Inheritance

Decorators follow entity enheritance, which means: say you have an entity A having a decorator, and entity B extends A. You perform a db action on B, now the decorator from entity A is used. Inside the decorator, you can distinguish types (A or B ) by using entity.get__Type(). You can get properties from B inside the decorator with the same functions as you would from A (e.g. B.getName()), any B specific fields can be obtained with B.get("fieldname").