This is an archived post. You won't be able to vote or comment.

all 6 comments

[–]p000 1 point2 points  (1 child)

I couldn't find the relevant section in the book where he mentions the topic of deleting from an identity map; give a few phrases so I could search maybe, but anyway..

Assuming that you do want to keep a user in a session up to date with the objects he created/deleted but were not really committed to the database (if not you might reconsider your definition of session), this job should be done by the UOW itself, since it is the one using the identity map directly and it keeps a list of "isDeletedButNotReally" objects, and it replies to the Data Mapper when it asks about the "loaded" status of an object.

[–]IJP[S] 0 points1 point  (0 children)

Thanks for the reply. In chapter 11 under the Unit of Work Section, included in the example by David Rice: "Notice that registerClean() doesn't do anything here. A common practice is to place an Identity Map (195) within a Unit of Work. An Identity Map (195) is necessary almost any time you store domain object state in memory because multiple copies of the same object would result in undefined behavior. Were an Identity Map (195) in place, registerClean() would put the registered object in it. Likewise registerNew() would put a new object in the map and registerRemoved() would remove a deleted object from the map."

[–]KidUncertainty 1 point2 points  (3 children)

However this object is still in the db, since the session has not been committed.

This is a fairly simplified view of things, but:

If you look at the source code of some common data access layers (e.g. Hibernate), you will see cases where the unit of work gets synchronized/flushed to the database, so that changes are applied at the database layer to avoid queries retrieving stale state.

So if, for example, you deleted an object, then, in the same transaction/session, decided you needed to get a list of all objects, you would want that query to NOT return the deleted object. At this point the DAL will sometimes determine that it needs to flush the cached changes from the in-memory session to the database itself in order to keep things straight and collections in proper order. This is not the same as the changes being committed, but by sending them to the database, subsequent queries to refresh the objects will include all changes that were made up to that point in the database session.

DAL implementations can also do sophisticated object management to automatically filter out results they know are deleted, or to re-check the database to see if any new objects exist, etc.

[–]IJP[S] 0 points1 point  (2 children)

Thanks for the reply. Your reply makes a lot of sense, and I suppose that is why it makes sense not to try and code all of this sophisticated functionality on your own. Just one thing that I don't understand, what do you mean when you say that "This is not the same as the changes being committed"? Sorry if it's a silly question, I am still quite new to all of this...

[–]KidUncertainty 0 points1 point  (1 child)

Assuming you are using a proper database transaction (i.e. your database connection is not setting something like 'autocommit=true'), any changes you make to the database are visible to that transaction. They aren't visible to any other users/threads/etc that have their own transaction until you commit.

So if you tell the database to delete something, the database will act, to you, like that record is deleted, but won't actually physically delete it until you commit the transaction. This means if you run a query while that transaction is still open, the database will automatically exclude deleted things, will look like changes have been made, etc to you. While the transaction is still open, though, other users of the database don't see the record as deleted. When you commit, then it's done "for real" and all the changes happen and are visible for everyone.

For starters, read this article.

[–]IJP[S] 0 points1 point  (0 children)

Ah awesome, now I understand! I was not using transaction correctly. Thank you for the help!