Ok, I’m about to divulge to the world one of my little programming gems – something I’ve used on every single project for almost the last 4 years now. It is very easily translated to any other OO language as well, especially C# for the .NET/Hibernate.NET folks.

I haven’t been keeping it secret or anything, I guess I just never took the time to write it out for general public. So when someone reading my blog asked to see the source for it, I figured now is as good a time as any to write about it.

It is a root/base class from which all my persistent Classes extend. To put it another way, if I have Java instances that I need to store to a database through Hibernate or some other EIS API, every one of those instance Classes extend from this base class (either directly or indirectly in an OO hierarchy). Every entity in every persistent class hierarchy I’ve used in the last 4 years has it as its hierarchy root – it is versatile and resilient ๐Ÿ™‚

Now, if you’ve used Hibernate much before, you’ll realize this isn’t the world’s biggest secret – most people do something similar. Its a great idea. I’m just making mine available to the world in case there are those that haven’t done something similar yet, or if those who have just want to see how I do things.

What is this class called? I call it Entity. In Object-Relational Mapping circles, the word Entity often comes up in the context of object persistence discussions – “Persistent Object”, “Persistent Entity”, “Base Persistent Object”, etc. I personally think “Entity” is elegantly succinct, so I stuck with it.

Before going on to the code, I just want to clarify my Entity class a little bit. It is not an implementation of what many call the “Active Record design pattern”. This means this base entity class doesn’t know how to persist or delete itself via any save() or delete() methods.

I’m a firm believer in keeping persistence logic code out of my domain model to prevent the chance of polluting the rest of my application with those APIs (it goes beyond API pollution too – google the principal of “Low Coupling, High Cohesion” for more info). Anyway, and I relegate all such logic to DAO implementations and all of my domain classes remain nice and clean.

Ok, so now that point is settled, here’s my oh-so-yummy-and-incredibly-useful Entity class:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.Serializable;

/**
 * Root parent class for all persistent object entities.
 *
 * <strong>NOTE:</strong> Subclasses should <em>always</em> provide a unique
 * onEquals() and hashCode() implementation and these should not use
 * the id() property - i.e. always keep in mind the subclass' 'business keys'
 * when implementing those methods.
 *
 * @author Les Hazlewood
 */
public abstract class Entity implements Identifiable, Serializable, Cloneable {

    protected transient final Log log = LogFactory.getLog(getClass());

    /**
     * RDBMS Primary key, aka 'surrogate key'.  Long surrogate keys are best
     * for RDBMS performance (for many reasons that can't be expanded on here)
     * But, every single table should _always_ have a 'business key' - a unique
     * constraint across one or more columns that guarantee row duplicates will
     * never occur. Null value means the object hasn't been persisted to the RDBMS
     */
    protected Long id = null;

    /**
     * Used for optimistic locking to ensure two threads (even across different machines)
     * don't simultaneously overwrite entity state - not necessarily used by all subclasses.
     * Pretty much required if in a high-concurrency environment and/or if using distributed
     * caching in a cluster.   It (and its corresponding mutator methods) is not called
     * 'version' to prevent eliminating that name from subclasses should the business
     * domain naming conventions require it.  Also 'entityVersion' is self-documenting
     * and leaves little room for incorrect interpretation.
     */
    protected int entityVersion = -1;

    public Entity() {
    }

    public Long getId() {
        return this.id;
    }

    /**
     * Should <em>never</em> be called directly.  Only via Hibernate or other EIS framework, since
     * they get the ID from the RDBMS directly.
     *
     * This method can be removed entirely if the EIS framework supports setting the ID property
     * directly (e.g. through reflection).  Hibernate does support this, it is called 'property access'.
     */
    public void setId(Long id) {
        this.id = id;
    }

    public int getEntityVersion() {
        return this.entityVersion;
    }

    /**
     * For the same reasons as the setId() method, this should only be called by a
     * framework and never directly.  Can be removed if the framework supports property access.
     */
    public void setEntityVersion(int entityVersion) {
        this.entityVersion = entityVersion;
    }

    /**
     * This method is declared final and does a lot of performance optimization:
     *
     * It delegates the actual "equals" check to subclasses via the onEquals method, but
     * it will only do so if the object for equality comparison is
     *
     * <ol>
     * <li>not the same memory location as the current object (fast sanity check)</li>
     * <li>of type Entity or one of its subclasses</li>
     * <li>Does not have the same id() property</li>
     * </ol>
     *
     * #3 is important:  this is because if two different entities have the ID property
     * already populated, then they have already been inserted in the database, and
     * because of unique constraints on the database (i.e. your 'business key'), you
     * can <em>guarantee</em> that the objects are not the same and there is no need
     * to incur attribute-based comparisons for equals() checks.
     *
     * This little technique is a massive performance improvement given the number of times
     * equals checks happen in most applications.
     */
    public final boolean equals(Object o) {
        if (o == this) {
            return true;
        }

        if (o instanceof Entity) {
            Entity e = (Entity) o;
            Long thisId = getId();
            Long otherId = e.getId();
            if (thisId != null && otherId != null) {
                return thisId.equals(otherId) &&
                        getClass().isAssignableFrom(e.getClass());
            } else {
                return onEquals(e);
            }
        }

        return false;
    }

    /**
     * Subclasses must do an equals comparison based on business keys here.
     */
    public abstract boolean onEquals(Entity e);

    public abstract int hashCode();

    /**
     * If children classes override they must always call super.clone() to get the object
     * with which they manipulate further to clone remaining attributes.  Never acquire
     * the cloned object directly via 'new' operator (this is true regardless of this Entity
     * class or not).
     */
    @Override
    @SuppressWarnings({"CloneDoesntDeclareCloneNotSupportedException"})
    public Object clone() {

        Entity e;
        try {
            e = (Entity) super.clone();
        } catch (CloneNotSupportedException neverHappens) {
            // Should _never_ happen since this class is Cloneable and
            // a direct subclass of Object
            throw new InternalError("Unable to clone object of type [" + getClass().getName() + "]");
        }

        e.setId(null);
        e.setEntityVersion(-1);
        return e;
    }

    /**
     * Returns a StringBuffer representing the toString function of the class implementation. This
     * should be overridden by all children classes using <tt>super.toStringBuffer()</tt> as the
     * base, adding properties to the returned StringBuffer.
     *
     * @return a <tt>StringBuffer</tt> reperesenting the <tt>toString</tt> value of this object.
     */
    public StringBuffer toStringBuffer() {
        StringBuffer sb = new StringBuffer();
        sb.append("id=").append(getId());
        return sb;
    }

    /**
     * Returns toStringBuffer().toString().  Declared as 'final' to require subclasses to override
     * the {@link #toStringBuffer()} method, a cleaner and better performing mechanism for toString();
     *
     * @return toStringBuffer().toString()
     */
    public final String toString() {
        return toStringBuffer().toString();
    }
}

You’ll notice that the Entity class also implements Identifiable, which is nothing more than this:

/**
  * @author Les Hazlewood
  */
public interface Identifiable {
    Long getId();
}

This doesn’t look too useful, but I have another interface that subclasses (‘sub interfaces’?) it:

/**
  * @author Les Hazlewood
  */
public interface Referenceable extends Identifiable {
    String getLabel();
}

Referenceable is particularly useful in GUI/web code where you might want to present a list of options to the user, and the list-generation code only cares about IDs and readable strings to present to the user. For example, a drop-down/select box:

$referenceable.label

The list generation code doesn’t care if the collection it is processing has User elements, or EmailAddress elements, or anything else. Ahh, the beauty of polymorphism ๐Ÿ™‚

Anyway, I hope you find this Entity class as useful as I have – it is the staple by which I develop all of my domain models in Java.

Cheers,

Les