.. _identity:

========
Identity
========

Since a lot revolves around an Entity’s unique identity, let us dig deeper into different identity creation strategies.

An Entity's identity may or may not also be practical for finding or matching. If the entity holds a globally unique identifier (like your tax identity, or SSN), the field can also serve as a unique identifier for the entity. But more often than not, you are left with the task of having to generate a unique identity to represent non-unique data attributes (like People and their names). In the latter case, application may allow for searching on names of people, but may not make sense to match by a randomly generated unique identifier.

Identities can be stored in their native forms, as integers or strings, but it is often better to use Value Objects as holders of unique identity. Value Objects are immutable, which ensures identity stability, and any behavior specific to the kind of identity is centralized. Encapsulating identity behavior, however simple, keeps the know-how from leaking into other parts of the model and into clients. It also comes handy if you ever decide to move from one identity format to another (say, from running integers to UUIDs).

Here are some common identity creation strategies, in the order of increasing complexity:

• The application internally generates an identity using an algorithm that ensures uniqueness. We can get a library or framework to do this for us, but it can be done by the application.
• The application relies on a persistence store, such as a database, to generate a unique identity.
• Another Bounded Context (2) (system or application) has already determined the unique identity. It is input or selected by the user from a set of choices.

1. User Provides Identity
=========================

The user provides one or more original unique values as input to the application. The application must ensure that they are unique.

This is a straightforward approach in which the user manually enters the details of unique identity into the application. But there can be complications.

One complication is relying on users to produce quality identities. The identity may be unique but incorrect. For example, the user could provide his misspelled full name as a unique identifier. Since identities are typically immutable, users shouldn’t be allowed to change them after Entity creation. Even if we don't apply the rule in this case, and allow users to correct identity values, we have to handle the case of other entities of the application holding the user's identity for linkages.

We always have the option to include user-entered values as Entity properties available for matching, but not to use them for unique identity. Simple properties are more easily modified as part of the normal operational state of the Entity that changes over time. In that case we will need to use another means to obtain unique identity.

2. Application Generates Identity
=================================

There are highly reliable ways to auto-generate unique identities, that remain valid even when the application is clustered or otherwise distributed across multiple computing nodes. There are identity creation patterns that can, to a much greater degree of certainty, produce a completely unique identity.

Another common approach is to produce multiple string outputs that are concatenated together into a single textual representation. The strings could be:

1. Time in milliseconds on the computing node
2. IP address of the computing code
3. Object identity of the factory object instance within the virtual machine (Java)
4. Random number generated by the same generator within the virtual machine (Java)

The universally unique identifier (UUID), or globally unique identifier (GUID), is another approach.

UUID is a relatively fast identity to generate, requiring no interaction with the outside world, such as a persistence store. The UUID generator can keep up with high volume identity generation. But we can even cache a number of UUID instances for higher-performance domains, refilling the cache in the background. If cached UUID instances are lost due to server restart, there are no gaps in identities because they are all based on random, manufactured values. Refilling the cache on server restart has no negative consequences of abandoned values.

A full UUID is usually appropriate when it can be hidden from users and human-readable reference techniques can be used. In the earlier example of people, we could use a unique username along with the unique identifier as a visually identifiable piece of information for the users.

3. Persistence Mechanism Generates Identity
===========================================

Delegating the generation of unique identity to a persistence mechanism has some unique advantages. If we call on the database for a sequence or incrementing value, it will always be unique.

Depending on the range needed, the database can generate a unique 2-byte, 4-byte, or 8-byte value. In Python, the primitive int data type can store and grow with the size of integers as necessary.

One possible downside is performance. It can take significantly longer to go to the database to get each value than to generate identities in the application. Much depends on database load and application demand. One way around this is to cache sequence/increment values in the application, such as in a Repository. This can work well, but we lose a good number of unused values when server nodes must be restarted.

Pre-allocation and caching are not an issue if the model can suffice with late identity generation.

Other Considerations
====================

Timing of Identity Generation
-----------------------------

Identity generation can occur either early, as part of the object’s construction, or late, as part of its persistence. While it is very much possible to generate identities as part of persistence, Protean advocates and prefers to generate identities early, as soon as the object is constructed.

A very simple straightforward domain concept can do with late identity generation. This is assuming the entity creation process is isolated, and no other aspect of the domain is interested in referring to the entity. But any reasonably complex DDD application will be unable to stick to this restriction. The application is expected to have multiple aggregates and bounded contexts, and will use Domain Events to communicate across them.

When an aggregate generates an event as part of a business process, the event payload carries unique identifiers of entity objects. Unless you want to support a split transaction, one to persist the primary entity and retrieve its identifier, and then to generate a Domain Event with the data (which is again persisted for posterity sake), you are stuck with generating the identity early.

There is another problem that can occur when identity generation is delayed until the Entity is persisted. It occurs when two or more new Entities must be added together, but their identity has not yet been assigned, making them equal to the other new ones (for example, null, or 0, or -1). If the Entity’s equals() method compares identities and if you are using a `set` like data structure to hold the entities, those newly added will appear to be the same object. Only the first object added will be contained, and all others will be excluded.

Protean prefers and advocates early identity generation for Entities and Aggregates.

Surrogate Identity
------------------

<WIP>

Identity Stability
------------------

Protean prevents modification of identifiers once they are on entities.
<WIP>
