Identity Field Pattern

This pattern belongs to Object-Relational Structural Patterns Catalog and this Catalog belongs to Patterns of Enterprise Application Architecture.

Intent

Saves a database ID field in an object to maintain an identity between an in-memory object and a database row.

Explanation

Let's understand the Identity Field Design Pattern with an example. We have a person table which contains id, name, age, and gender as columns.
The class diagram for Person class:
The person database table:
idnameagegender
1ramesh28male
2prakash28male
class Person{
    private long id;
    private String name;
    private int age;
    private String gender;
    // standard getter and setter methods.
}
1. id column is the primary key in a database that is unique and distinguishes each row.

2. In the above table, there are two rows and which are uniquely identified by the primary key.

3. The relational database uses the primary key to identify one row from another. 

The id column with datatype long represents the identity field.

How It Works

Choosing Your Key

The first issue is what kind of key to choosing in your database. Let's discuss some of the techniques briefly.
The first concern is whether to use meaningful or meaningless keys
  • A meaningful key is something like the U.S. Social Security number for identifying a person.
  • A meaningless key is essentially a random number the database dreams up that’s never intended for human use. The danger with a meaningful key is that, while in theory, they make good keys, in practice they don’t.To work at all, keys need to be unique; to work well, they need to be immutable.
The next concern is simple versus compound keys. A simple key uses only one database field; a compound key uses more than one.

The advantage of a compound key is that it’s often easier to use when one table makes sense in the context of another. A good example is orders and line items, where a good key for the line item is a compound of the order number and a sequence number makes a good key for a line item.

Always prefer long data type for primary keys. Strings can also work, but equality checking may be slower and incrementing strings is a bit more painful.

Representing the Identity Field in an Object

The simplest form of Identity Field is a field that matches the type of key in the database. Thus, if you use a simple integral key, an integral field will work very nicely.

For example: In Person java class, the id field is an identity field that matches the primary key in a database table.

Getting a New Key

There are three basic choices to get the key:
  1. Get the database to auto-generate
  2. Use a GUID
  3. Generate your own
Auto-generate: The auto-generate route should be the easiest. Each time you insert data into the database, the database generates a unique primary key without you having to do anything. It sounds too good to be true, and sadly it often is. Not all databases do this the same way.

Using a GUID: A GUID (Globally Unique IDentifier) is a number generated on one machine that’s guaranteed to be unique across all machines in space and time. Often platforms give you the API to generate a GUID. The only disadvantage to a GUID is that the resulting key string is big, and that can be an equally big problem.

Custom key generation: The last option is rolling your own. A simple staple for small systems is to use a table scan using the SQL max function to find the largest key in the table and then add one to use it. Sadly, this read-locks the entire table while you’re doing it, which means that it works fine if inserts are rare, but your performance will be toasted if you have inserts running concurrently with updates on the same table.

When to Use It

Use Identity Field when there’s a mapping between objects in memory and rows in a database.

Sample Code

Person class with id field as an identity field.
class Person{
    private long id;
    private String name;
    private int age;
    private String gender;
    // standard getter and setter methods.
}
DomainObject with id (long datatype) as an identity field.
class DomainObject {
    public const long PLACEHOLDER_ID = -1;
    public long Id = PLACEHOLDER_ID;
    public Boolean isNew() {return Id == PLACEHOLDER_ID;}
}

References


Comments