473,473 Members | 1,853 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Identity mapper

Has anyone written or using an identity mapper design pattern in an
enterprise framework?

The identity mapper pattern is described in Martin Fowler's Patterns of
Enterprise Application Architecture. It means that subsequent loads of the
same object from the database will result in the same object in memory.

Album album1 = Album.Read(10);

Album album2 = Album.Read(10);

Assert.AreSame(album1, album2);

There are some caveats; there is one identity mapper per transaction not per
appdomain and if there is no transaction then a separate identity mapper is
created for that too. Also, when there are no more references to that
object in play then the identity mapper needs to remove the object from its
own internal store. If it did not do this then it means that the identity
mapper is nothing more than a cache that would not be aware of changes to
the underlying data in the db.

This is where my question lies. How can you work out when an object falls
out of scope to notify the identity mapper that the object count has reduced
by one? You could implement IDisposable but then you would need to call
'using' everywhere - not pretty. You could hook into the destructor but then
the behaviour of your code would rely on the scheduling of the garbage
collector - even worse.

You need to ensure that if the following function is called twice in
succession then it actually hits the database twice. If the Album's
destructor was left to notify the identity mapper of album1 falling out of
scope then this notification would not be sent until way after the Function1
was called for the second time.

void Function1()

{

Album album1 = Album.Read(10);

}

Any ideas?

Regards

Dave A
Mar 29 '06 #1
3 1562
Dave A wrote:
Has anyone written or using an identity mapper design pattern in an
enterprise framework?
yes. In O/R mapper land, it's called 'uniquing', which means that you
return the same entity instance for a subsequent request of the same
data.
The identity mapper pattern is described in Martin Fowler's Patterns
of Enterprise Application Architecture. It means that subsequent
loads of the same object from the database will result in the same
object in memory.
Album album1 = Album.Read(10);
Album album2 = Album.Read(10);
Assert.AreSame(album1, album2);

There are some caveats; there is one identity mapper per transaction
not per appdomain and if there is no transaction then a separate
identity mapper is created for that too. Also, when there are no
more references to that object in play then the identity mapper needs
to remove the object from its own internal store. If it did not do
this then it means that the identity mapper is nothing more than a
cache that would not be aware of changes to the underlying data in
the db.
it never knows what happens to the DB, as you can't possibly know
that. Take for example a webfarm, or a BL server farm. Multiple
servers, targeting the same large DB server. You don't know what
happens on server A with entity E when your code runs on server B
working with the same entity E.
This is where my question lies. How can you work out when an object
falls out of scope to notify the identity mapper that the object
count has reduced by one? You could implement IDisposable but then
you would need to call 'using' everywhere - not pretty. You could
hook into the destructor but then the behaviour of your code would
rely on the scheduling of the garbage collector - even worse.
You should take a step back. It looks great on paper, this identity
mapper pattern, but in practise it's very hard to implement in a
multi-appdomain system, especially since .NET doesn't have
cross-appdomain object awareness.

Entities are actually pretty abstract things. An entity object isn't
the entity, it's the data inside the entity object which forms the
entity. This means that the actual habitat of the entity isn't an
object, but the DB and in memory you're simply using a mirror, stored
in a container, the Entity object.

If you don't use this approach, but stick with 'the entity == the
entity object', you can't talk about the same 'customer' when you have
two threads on two different machines reading the same data from the
DB. As every sane person will say "that's the same customer", the
entity lives in the db, or better: lives in the shared persistent
storage accessed by all code. This is all highly semantical, but for
understanding what's going on, it's crucial.

Now, Apple's O/R mapper (yes, they have an O/R mapper, which is
actually pretty good, click this url to see what they've cooked up:
http://developer.apple.com/macosx/coredata.html) introduced the concept
of a Context. An entity object is unique within a context. A context is
pure semantical. You can have multiple contexts in one routine if you
like.

LLBLGen Pro, the o/r mapper framework I now work on for 3 years uses
this concept as well. It's actually pretty simple. When you fetch an
entity from the DB (which thus means the data) and store it in an
entity object (its container), the data might be the same as already
loaded versions of that same entity, but the container is a different
instance. To use a Context object you can grab the same instance. So,
if you have a context object in your routine, so it represents a
semantical context, you can pass it to the o/r mapper core when
fetching data and you get for the same entity, the same entity instance
back as was found in the passed in context. You can also consult the
context to get the instance of the entity container for a particular
entity:
CustomerEntity c = (CustomerEntity)myContext.Get(newlyFetchedCustomer );

c is either newlyFetchedCustomer if the entity isn't found in
myContext, or it's the instance which was already known by the context.
'Known by the context' is crucial here: you can have more context
objects in your routine or at runtime, and an entity instance is unique
for a given context, not for a given app at runtime.
You need to ensure that if the following function is called twice in
succession then it actually hits the database twice. If the Album's
destructor was left to notify the identity mapper of album1 falling
out of scope then this notification would not be sent until way after
the Function1 was called for the second time.

void Function1()
{
Album album1 = Album.Read(10);
}

Any ideas?


You shouldn't worry about destruction. After all, the context knows
the instance, so it only goes out of scope when the context goes out of
scope.

FB
--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Mar 29 '06 #2
Many thanks.

I am familiar with this idea of context that has been used by a couple of
different O/R mappers and this leads me on to another point that I am sure
you will be able to shed some light on...

In .Net2 we have the new TransactionScope object. The scope of
TransactionScope seems to be very similiar to the scope of Contexts.

In LLBLGen Pro an entity instance is unique within a context
In an Identity Map and entity instance is unique with in a transaction

I wonder if a brand new O/R mapper were created for .Net2 would the designer
of such an O/R mapper abandon the concept of Contexts and create a new
TransactionScope object (maybe called BusinessScope) that would bring
together transactions and contexts into one concept?

Contexts and transactions start to sound very similar? Only now with
TransactionsScope is the similarity more clear.

Your throughts?

Regards
Dave A

"Frans Bouma [C# MVP]" <pe******************@xs4all.nl> wrote in message
news:xn***************@news.microsoft.com...
Dave A wrote:
Has anyone written or using an identity mapper design pattern in an
enterprise framework?


yes. In O/R mapper land, it's called 'uniquing', which means that you
return the same entity instance for a subsequent request of the same
data.
The identity mapper pattern is described in Martin Fowler's Patterns
of Enterprise Application Architecture. It means that subsequent
loads of the same object from the database will result in the same
object in memory.
Album album1 = Album.Read(10);
Album album2 = Album.Read(10);
Assert.AreSame(album1, album2);

There are some caveats; there is one identity mapper per transaction
not per appdomain and if there is no transaction then a separate
identity mapper is created for that too. Also, when there are no
more references to that object in play then the identity mapper needs
to remove the object from its own internal store. If it did not do
this then it means that the identity mapper is nothing more than a
cache that would not be aware of changes to the underlying data in
the db.


it never knows what happens to the DB, as you can't possibly know
that. Take for example a webfarm, or a BL server farm. Multiple
servers, targeting the same large DB server. You don't know what
happens on server A with entity E when your code runs on server B
working with the same entity E.
This is where my question lies. How can you work out when an object
falls out of scope to notify the identity mapper that the object
count has reduced by one? You could implement IDisposable but then
you would need to call 'using' everywhere - not pretty. You could
hook into the destructor but then the behaviour of your code would
rely on the scheduling of the garbage collector - even worse.


You should take a step back. It looks great on paper, this identity
mapper pattern, but in practise it's very hard to implement in a
multi-appdomain system, especially since .NET doesn't have
cross-appdomain object awareness.

Entities are actually pretty abstract things. An entity object isn't
the entity, it's the data inside the entity object which forms the
entity. This means that the actual habitat of the entity isn't an
object, but the DB and in memory you're simply using a mirror, stored
in a container, the Entity object.

If you don't use this approach, but stick with 'the entity == the
entity object', you can't talk about the same 'customer' when you have
two threads on two different machines reading the same data from the
DB. As every sane person will say "that's the same customer", the
entity lives in the db, or better: lives in the shared persistent
storage accessed by all code. This is all highly semantical, but for
understanding what's going on, it's crucial.

Now, Apple's O/R mapper (yes, they have an O/R mapper, which is
actually pretty good, click this url to see what they've cooked up:
http://developer.apple.com/macosx/coredata.html) introduced the concept
of a Context. An entity object is unique within a context. A context is
pure semantical. You can have multiple contexts in one routine if you
like.

LLBLGen Pro, the o/r mapper framework I now work on for 3 years uses
this concept as well. It's actually pretty simple. When you fetch an
entity from the DB (which thus means the data) and store it in an
entity object (its container), the data might be the same as already
loaded versions of that same entity, but the container is a different
instance. To use a Context object you can grab the same instance. So,
if you have a context object in your routine, so it represents a
semantical context, you can pass it to the o/r mapper core when
fetching data and you get for the same entity, the same entity instance
back as was found in the passed in context. You can also consult the
context to get the instance of the entity container for a particular
entity:
CustomerEntity c = (CustomerEntity)myContext.Get(newlyFetchedCustomer );

c is either newlyFetchedCustomer if the entity isn't found in
myContext, or it's the instance which was already known by the context.
'Known by the context' is crucial here: you can have more context
objects in your routine or at runtime, and an entity instance is unique
for a given context, not for a given app at runtime.
You need to ensure that if the following function is called twice in
succession then it actually hits the database twice. If the Album's
destructor was left to notify the identity mapper of album1 falling
out of scope then this notification would not be sent until way after
the Function1 was called for the second time.

void Function1()
{
Album album1 = Album.Read(10);
}

Any ideas?


You shouldn't worry about destruction. After all, the context knows
the instance, so it only goes out of scope when the context goes out of
scope.

FB
--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------

Mar 29 '06 #3
Dave A wrote:
Many thanks.

I am familiar with this idea of context that has been used by a
couple of different O/R mappers and this leads me on to another point
that I am sure you will be able to shed some light on...

In .Net2 we have the new TransactionScope object. The scope of
TransactionScope seems to be very similiar to the scope of Contexts.

In LLBLGen Pro an entity instance is unique within a context
In an Identity Map and entity instance is unique with in a transaction

I wonder if a brand new O/R mapper were created for .Net2 would the
designer of such an O/R mapper abandon the concept of Contexts and
create a new TransactionScope object (maybe called BusinessScope)
that would bring together transactions and contexts into one concept?

Contexts and transactions start to sound very similar? Only now with
TransactionsScope is the similarity more clear.
Not necessarily, IMHO. The 'transaction' name is a bit odd. Most
people think of an atomic set of actions to manipulate data in a
persistent storage. However used by your example, it's also a set of
actions in memory. I'm not that convinced TransactionScope is meant for
that. It's more a scope object to have persistent storage manipulation
transactionable across systems and objects (COM+/Enterprise services
etc.)

FB

Regards
Dave A

"Frans Bouma [C# MVP]" <pe******************@xs4all.nl> wrote in
message news:xn***************@news.microsoft.com...
Dave A wrote:
Has anyone written or using an identity mapper design pattern in an
enterprise framework?


yes. In O/R mapper land, it's called 'uniquing', which means that
you return the same entity instance for a subsequent request of the
same data.
The identity mapper pattern is described in Martin Fowler's Patterns >> of Enterprise Application Architecture. It means that
subsequent >> loads of the same object from the database will result
in the same >> object in memory.

Album album1 = Album.Read(10);
Album album2 = Album.Read(10);
Assert.AreSame(album1, album2);

There are some caveats; there is one identity mapper per transaction >> not per appdomain and if there is no transaction then
a separate >> identity mapper is created for that too. Also, when
there are no >> more references to that object in play then the
identity mapper needs >> to remove the object from its own internal
store. If it did not do >> this then it means that the identity
mapper is nothing more than a >> cache that would not be aware of
changes to the underlying data in >> the db.

it never knows what happens to the DB, as you can't possibly know
that. Take for example a webfarm, or a BL server farm. Multiple
servers, targeting the same large DB server. You don't know what
happens on server A with entity E when your code runs on server B
working with the same entity E.
This is where my question lies. How can you work out when an object
falls out of scope to notify the identity mapper that the object
count has reduced by one? You could implement IDisposable but then
you would need to call 'using' everywhere - not pretty. You could
hook into the destructor but then the behaviour of your code would
rely on the scheduling of the garbage collector - even worse.


You should take a step back. It looks great on paper, this identity
mapper pattern, but in practise it's very hard to implement in a
multi-appdomain system, especially since .NET doesn't have
cross-appdomain object awareness.

Entities are actually pretty abstract things. An entity object isn't
the entity, it's the data inside the entity object which forms the
entity. This means that the actual habitat of the entity isn't an
object, but the DB and in memory you're simply using a mirror,
stored in a container, the Entity object.

If you don't use this approach, but stick with 'the entity == the
entity object', you can't talk about the same 'customer' when you
have two threads on two different machines reading the same data
from the DB. As every sane person will say "that's the same
customer", the entity lives in the db, or better: lives in the
shared persistent storage accessed by all code. This is all highly
semantical, but for understanding what's going on, it's crucial.

Now, Apple's O/R mapper (yes, they have an O/R mapper, which is
actually pretty good, click this url to see what they've cooked up:
http://developer.apple.com/macosx/coredata.html) introduced the
concept of a Context. An entity object is unique within a context.
A context is pure semantical. You can have multiple contexts in one
routine if you like.

LLBLGen Pro, the o/r mapper framework I now work on for 3 years uses
this concept as well. It's actually pretty simple. When you fetch an
entity from the DB (which thus means the data) and store it in an
entity object (its container), the data might be the same as already
loaded versions of that same entity, but the container is a
different instance. To use a Context object you can grab the same
instance. So, if you have a context object in your routine, so it
represents a semantical context, you can pass it to the o/r mapper
core when fetching data and you get for the same entity, the same
entity instance back as was found in the passed in context. You can
also consult the context to get the instance of the entity
container for a particular entity:
CustomerEntity c =
(CustomerEntity)myContext.Get(newlyFetchedCustomer );

c is either newlyFetchedCustomer if the entity isn't found in
myContext, or it's the instance which was already known by the
context. 'Known by the context' is crucial here: you can have more
context objects in your routine or at runtime, and an entity
instance is unique for a given context, not for a given app at
runtime.
You need to ensure that if the following function is called twice

in >> succession then it actually hits the database twice. If the
Album's >> destructor was left to notify the identity mapper of
album1 falling >> out of scope then this notification would not be
sent until way after >> the Function1 was called for the second time.
void Function1()
{
Album album1 = Album.Read(10);
}

Any ideas?


You shouldn't worry about destruction. After all, the context knows
the instance, so it only goes out of scope when the context goes
out of scope.

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Mar 29 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Eugene | last post by:
I have a table EugeneTest(id_num, fname, minit, lname) where field "id_num" is type IDENTITY and has UNIQUE constraint Let's say 2 user execute this code at the same time: DECLARE @return...
4
by: brent.ryan | last post by:
How do I get the next int value for a column before I do an insert in MY SQL Server 2000? I'm currently using Oracle sequence and doing something like: select seq.nextval from dual; Then I...
1
by: mirnazim | last post by:
Hi, I have to develop a web based information system for an educational institution. It is going to be a 100% OO code. Therefore I also need an Object Relational Mapper. I have not used any object...
8
by: Razak | last post by:
Hi, I have a class which basically do Impersonation in my web application. From MS KB sample:- ++++++++++++++++++++code starts Dim impersonationContext As...
21
by: Islamegy® | last post by:
I was spending time to learn the use of strongly typed collection instead of Dataset/datatable and using Enterprise Library Applictations block.. Recently i discovered there is alot of project...
17
by: Fregas | last post by:
I'm the lead developer at my company and i'm looking into O/R Mappers again. I've used LLBLGen and Wilson ORM and played with some others. I prefer WORM because of its simplicity and the fact that...
5
by: Veeru71 | last post by:
Given a table with an identity column (GENERATED BY DEFAULT AS IDENTITY), is there any way to get the last generated value by DB2 for the identity column? I can't use identity_val_local() as...
0
by: Iceman | last post by:
To help speed up HTML image mapping try out Precision HTML Image Mapper from Hackett Solutions Inc. http://www.hackettsolutions.com/PrecisionHTMLImageMapper.aspx The Precision HTML Image...
5
by: Flip Rayner | last post by:
Hi, We are creating a URL mapper that translates from one URL (yucky - badly formatted), to a nicely formatted URL. The mapper acts as a proxy type website above the source website, processing...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.