Saves a database ID field in an object to maintain identity between an in-memory object and a database row.
- Overview
- How It Works
- Choosing Your Key
- Meaningful - Meaningless
- Simple - Compound
- Table-unique - Database-unique
- Representing the Identity Field in an Object
- Getting a New Key
- Choosing Your Key
- When to Use It
Further Reading M65yth mnjgb5r4fmfg67arinescu discusses several techniques for generating keys.
Reading data from a database is all very well, but in order to write data back you need to tie the database to the in-memory object system.
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.
A simple key uses only one database field; a compound key uses more than once.
- Compound keys are often easier to use when one table makes sense in the context of another.
- If you use simple keys everywhere, you can use the same code for all key manipulation.
- Compund keys require sepcial handling in concrete classes (with code generation this isn't a problem).
- Compund keys carry a bit of meaning, so be careful about the uniqueness and immutability.
- Mostly, you want a type with a fast equality operation and get next key operation
A table-unique key is unique across the table, which is what you need for a key in any case; a database-unique key is unique across every row in every table in the database.
- Database-unique key is often easier to do and allows you to use a single Identity Map
- It's pretty unlikely that you'll run out of numbers for new keys.
- You can reclaim keys from deleted objects.
- Database-unique key is easier to handle inheritance. If you're using Concrete Table Inheritance or Class Table Inheritance, life is much easier with keys that are unique to the hierarchy rather than unique to each table.
- The simplest form is a field that matches the type of the key in the database.
- For compound key, make a generic key class that can store a sequence of objects that act as the elements of the key.
- The key behavior for the key object is equality.
- Layer Supertype
- If you are using the same basic structure for all keys, you can do all of the key handling in it.
- Use it for default behavior and extend for exceptional cases in the particular subtypes.
- Get the database to auto-generate
- Alternative, is a database counter (select statement that references to a sequence)
- Use a GUID
- Generate your own
- Simple scan using SQL max function to find largest key (read-locks entire table).
- Separate key table, usually two columns: name, next available value.
- If you use database-unique keys, you'll have just one row in this table.
- If you use table-unique keys, you'll have one row for each table in the database.
- It's usually a good idea to put access to the key table in a separate transaction, so you only lock the row for a short transaction, if you rollback on your business transaction, you'll lose the key but, fortunately, numbers are "cheap".
-
Use Identity Field when there's a mapping between objects in memory and rows in a database. This is usually when you use Domain Model or Row Data Gateway.
-
Identity Map is an alternative to maintain the correspondence in systems where you don't want to store an Identity Field in the in-memory object. In this case, Identity Map would need to look up both ways: give me a key for an object or an object for a key. It's usually easier to store the key in the object.
-
You don't need this mapping if you're using Transaction Script, Table Module, or Tabla Data Gateway.
-
For a small object with value semantics, such as a money or date range object that won't have its own table, it's better to use Embedded Value.
-
For a complex graph of objects that doesn't need to be queried with the relational database, Serialized LOB is usually easier to write and gives faster performacne.