architect-handbook

Software Architect Handbook

View on GitHub

Identity Map

Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects using the map when referring to them.

Overview

An Identity Map keeps a record of all objects that have been read from the database in a single business transaction.

How It Works

The basic idea is to have a series of maps containing objects that have been pulled from the database. In a simple case, with an isomorphic schema, you’ll have one map per database table.

When you load an object from the database, you first check the map. If there’s an object in it that corresponds to the one you’re loading, you return it. If not, you go to the database, putting the objects into the map for future reference as you load them.

When to Use IT

Design & Implementation

Choice of Keys

The obvious choice is the primary key of the corresponding database table, this works well if the key is a single column and immutable.

Explicit or Generic

An Explicit Identity Map is accessed with distinct methods for each kind of object you need: such as findPerson(1).

A Generic Identity Map uses a single method for all kinds of objects, with perhaps a parameter to indicate which kind of object you need, such as find("Person", 1).

Your type of key affects the choice. You can only use a Generic Identity Map if all your objects have the same type of key. Otherwise, an Explicit Identity Map provides you with compile-time checking in a strongly typed language, and it has all the advantages of an explicit interface.

How Many

The decision varies between one map per class/table and one map for the whole session.

Where to Put Them

When To Use It

Example

Java

private Map people = new HashMap();

public static void addPerson(Person arg) {
  soleInstance.people.put(arg.getID(), arg);
}

public static Person getPerson(Long key) {
  return (Person) soleInstance.people.get(key);
}

public static Person getPerson(long key) {
  return getPerson(new Long(key));
}

long isn’t an object so you can’t use it as an index for a map. This is troublesome if you want to retrieve an object with a literal which you often do in test code, so you can include a getting method that takes a long to make testing easier.