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 void setId(int val) { id = val; }
public Customer(int id, String name) {
// Customer database adapter protected static RecordDescriptor red = new
RecordDescriptor public CustomerAdapter(Customer bizobj) { super(bizobj); } // Reconstruction } |
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
{ Customer updateCustomer(Customer customer)
throws StoreException { // 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 |