PriDE Design Patterns:
Separation of database and business concerns


The examples in the introduction all follow the approach of declaring the RecordDescriptor of an entity type as a static member of this type itself. As an advantage, the information about the actual data and its mapping to the database are kept in a single class making it easy to overview and maintain in the whole. This approach is reasonable for simple applications where the business logic does not require any abstraction from the physical persistence design or - on the contrary - is so complex, that the database access is completely encapsulated and data must be copied from physical entities to higher-level ones anyway. Althouh encapsulation of database operations is generally recommended (see also caching), the mapping between business entities and physical database records may be quite trivial and copying of data is not welcome with respect to maintainability and performance.

To achieve a separation of data and its database mapping, there is an alternative convenience class ObjectAdapter available. It provides the same functions like MappedObject (which actually is derived from ObjectAdapter), but as a difference its functions don't operate on the object itself but on a separate object. This object just has to provide getter and setter methods for all attributes which are supposed to be persisted. It may therefore be a pure value object according to the Java Bean conventions. The following example shows a variant of class Customer, which makes use of this separation of concerns:
 
 
// Customer business object
class Customer {
    private int id;
    private String name;

    public int getId() { return id; }
    public String getName() { return name; }

    public void setId(int val) { id = val; }
    public void setName(String val) { name = val; }

    public Customer(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

// Customer database adapter
class CustomerAdapter extends ObjectAdapter {

    protected static RecordDescriptor red = new RecordDescriptor
        (Customer.class, "customer", null, new String[][] {
            { "id",      "getId",      "setId" },
            { "name",    "getName",    "setName" },
        });

    public Customer getBizObject() {
        return (Customer)getEntity();
    }

    public CustomerAdapter(Customer bizobj) { super(bizobj); }

    // Reconstruction
    public CustomerAdapter(int id) {
        super(
new Customer(id, null));
        find();
    }

}

The class Customer in the example above is completely free from database mapping details and is reduced to the effective data. The class CustomerAdapter contains the mapping information and provides functions for data exchange with the database. It does not directly contain the data to exchange but keeps a reference to the business object which its operations refer to.

This approach is especially of interest in a layered system architecture as it is also recommened for the caching patterns. The database access may e.g. completely be decoupled from the business logic, following a facade pattern and making up a so-called data access object. The facade interacts with the business logic by business entities and primtive types and uses the mapping classes only internally. The following class fragment demonstrates such a concept:
 
class CustomerStore {

    Customer getCustomer(int id) throws StoreException {
        try {
            return new CustomerAdapter(id).getBizObject();
        }
        catch(NoResultsException nrx) { return null; }
        catch(SQLException sqlx) { throw new StoreException(sqlx); }
    }

    Customer updateCustomer(Customer customer) throws StoreException {
        try {
            new CustomerAdapter(customer).update();
            return customer;
        }
        catch(SQLException sqlx) { throw new StoreException(sqlx); }
    }

    // and so forth
}

PriDE's entity generator allows to generate separate mapping and value types by appropriate options. See the introduction for details.

Home Introduction Javadoc