PriDE Design Patterns: OIDs


One of the features mentioned in the feature list which is not directly covered by PriDE, are unique object identifiers (OIDs) for all entites of a system. A simple way to introduce these IDs is to provide an appropriate base class which all entites are derived from. As PriDE does not perform a database initialization but is based on an existing schema, the latter one must of course provide the required basic structure. I.e. all tables must have a common field that is suitable for identification purposes.
The following examples shows a base class definition using a numeric database field id for identification:
 
abstract class Entity extends MappedObject {
    protected static RecordDescriptor red = new RecordDescriptor
        (Entity.class, null, null, new String[][] {
            { "id", "getId", "setId" },
        });

    private int id;
    public int getId() { return id; }
    public void setId(int val) { id = val; }

    // Reconstructor
    protected Entity(int id) throws SQLException {
        this.id = id;
        find();
    }

    protected Entity() throws SQLException {
        id = IDGenerator.newID();
    }
}

The class Entity is defined abstract as it is only used as a base class and should not be instantiated directly. The specification of the database table is null as there is no relationship to a particular table yet. The definition of function getDescriptor() can be omitted for this abstract class. The function getKeyFields() is also not required as the primary key is the first attribute in the record descriptor, i.e. the ID. The question of automatic generation of object IDs is discussed later. In the example we assume that there is an ID generator available somehow. The class Customer from the PriDE introduction can now be defined as a derivation of that base class, inheriting the numeric identification attribute:
 
class Customer extends Entity {
    protected static RecordDescriptor red = new RecordDescriptor
        (Customer.class, "customer", Entity.red, new String[][] {
            { "name",    "getName",    "setName" },
        });
    protected RecordDescriptor getDescriptor() { return red; }

    private String name;
    public String getName() { return name; }
    public void setName(String val) { name = val; }

    // persistent construction
    public Customer(String name) throws SQLException {
        setName(name);
        create();
    }

    // reconstruction
    public Customer(int id) throws SQLException {
        super(id);
    }
}

Of course, it would be nice if polymorphism could be applied for all base operations for creation, update, deletion and selection in all classes derived from Entity. In fact, PriDE's reflection-based mapping mechanism is already suitable for polymorphic usage.:
 
Entity entity = new Customer("lessner");
entity.create(); // Creates a record in the customer table
entity.update(); // Updates a record in the customer table
entity.delete(); // Deletes a record from the customer table

If also a polymorphic reconstruction is required, the type information must be coded into the ID, e.g. by number sets like in an EAN-13 coding scheme (IDs 2000xxxxxxxxx are Customer records). The class Entity would have to be extended by a static method extracting the required entity type from the ID and invoking the type's constructor which gets passed the ID as the only parameter:
 
abstract class Entity extends MappedObject {
    // Definitions like above

    static Entity find(int id) throws Exception {
        Class entityClass = MyMap.findClassFromID(id);
        Constuctor ctor = entityClass.getConstructor(new Class[] { int.class });
        return (Entity)ctor.newInstance(new Object[] { new Integer(id) });
    }
}

Generating suitable IDs is of course still an open issue. PriDE doesn't provide any support for that yet (although it would be a nice utility class for the future). At least there are some general approaches which make an implementation quite easy:



Home Introduction Javadoc