Question

I have a domain object used in an identity map (the keys are the object's Id property).

Pseudocode:

map = new Mapping();
map[domainObj.Id] = 'foo';

I observe the object to tell me when it has been saved to the database:

domainObj.bind('saved', function() {
    map[domainObj.Id] = 'new foo!'
})

For new objects the Id field is empty and not populated until it is saved to the database.

And therein lies my problem. In the case of new objects, the lookup "map[domainObj.Id]" fails because the object's identity has changed after being saved!

What is the best way to use an object in an identity map like this?

Constraints:

  1. I am using a language that does not allow objects as keys in a mapping [JavaScript]
  2. The Id field must be generated on the server when saving a new object

Update

Thanks for the feedback. I really would like to have value objects mapped the same way as entities: just because the value object has not been saved does not mean it does not have a value to map to for my application. I am in fact mis-understanding what an identity map is (which, after re-reading the pattern definition, it turns out I am not truly using).

The solution I came up with is pretty much straight from Igor's answer: each object gets a random id assigned to it upon instantiation. It is unique, immutable and unchanging during the lifetime of the context in which the object lives. It is there for both entities from the db and new instantiations. The tweak for entities is that it is set to match the real identity of the object. This makes debugging a bit easier. This is the value I use as the key in the mapping.

Was it helpful?

Solution

Until an object gets the identity, it's just a value object. Only after the identity has been established it becomes an entity.

Until the object becomes an entity you cannot really put it in an identity map like yours - it doesn't make sense, since you cannot pull it out (since you don't have a unique key to find it).

One possible approach:

  1. Add a flag to the class which indicates the state of the object (new / saved).
  2. Implement a temporary (client-side) ID for these objects
  3. Optional:
    1. keep "new" objects in a separate identity map (if you cannot avoid ID conflicts between client and server IDs)
    2. keep "new" objects in the same identity map (if you can avoid ID conflicts between client and server IDs)
  4. Once the object has been saved, replace the client ID with the server ID, set the state to saved, move to the main identity map (if necessary).

See here about the entities vs. value objects

OTHER TIPS

Well, you'll have to find a way to postpone adding the object to the map until after it has been saved and assigned an ID.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top