package curam.inheritance; import curam.inheritance.Animal; import curam.inheritance.struct.AnimalDtls; import curam.util.persistence.EntityAdapter; import curam.util.persistence.helper.BasePlusConcreteTableImpl; import curam.util.type.DeepCloneable; abstract class AnimalImpl<CONCRETE_ENTITY extends Animal, CONCRETE_CLASS_DTLS_STRUCT extends DeepCloneable> extends BasePlusConcreteTableImpl<Long, CONCRETE_ENTITY, AnimalDtls, CONCRETE_CLASS_DTLS_STRUCT> implements Animal { protected AnimalImpl() { } @Override protected void setDiscriminator(final String value) { setAnimalType(value); } @Override protected EntityAdapter<Long, AnimalDtls> getBaseEntityAdapter() { return new AnimalAdapter(); } public String getName() { return getBaseRowDtls().name; } public void setName(final String value) { getBaseRowDtls().name = value; } protected void setAnimalType(final String value) { getBaseRowDtls().animalType = value; } }
There are a number of important features of this implementation which are explained below.
abstract class AnimalImpl<CONCRETE_ENTITY extends Animal, CONCRETE_CLASS_DTLS_STRUCT extends DeepCloneable> extends BasePlusConcreteTableImpl<Long, CONCRETE_ENTITY, AnimalDtls, CONCRETE_CLASS_DTLS_STRUCT>
The implementation class extends the helper class BasePlusConcreteTableImpl, which provides support for simple two-level class hierarchies (such as the one in this example).
BasePlusConcreteTableImpl is parameterized with the key type, the concrete entity interface and the Dtls structs used to store the abstract and base rows. AnimalImpl can directly supply two of these parameters (namely Long and AnimalDtls), but the name of the concrete interface and Dtls struct must be specified by the subclass implementations, and so the Animal class takes these types as parameters.
The class is package-protected and marked abstract. In this example the subclasses will be placed in the same code-package; if you require some of your subclasses to be in a different package, you will need to mark your abstract implementation class public.
protected AnimalImpl() { }
@Override protected void setDiscriminator(final String value) { setAnimalType(value); }
The class must override the BasePlusConcreteTableImpl.setDiscriminator method to store the discriminator in an appropriate column (in this example the animalType column). A protected setter is used to set the column value.
@Override protected EntityAdapter<Long, AnimalDtls> getBaseEntityAdapter() { return new AnimalAdapter(); }
The class must override the BasePlusConcreteTableImpl.getBaseEntityAdapter method to provider an entity adapter for retrieving and storing the database row for the base class.
The getters and setters make use of the BasePlusConcreteTableImpl.getBaseRowDtls to retrieve the Dtls struct for the base row (in this example an AnimalDtls struct).