> Great dicussion so far! So let's move beyond O/R mapping and 
> data layer encapsulation.

        uhoh :)

> The topic of transparent persistence has come up a few times. 
> I was wondering which techniques you guys employ in order to 
> achieve transparency.

        First of all, let me say that 'transparent persistence' is a
good candidate for buzzword bingo. What exactly is transparent
persistence? Is it the total absence of any persistence logic
whatsoever? Or is it the absence of a separate broker/adapter object so
all persistence behaviour is inside the object? 

        The first, the total absence of any persistence logic whatsoever
(i.e.: it's there, but you don't see it) is hardly possible. It means
that when an object goes out of scope, the persistence layer has to kick
in and check whether this object needs persistence or not. Not that easy
to implement (if ever), and also not what you want. The other is only
doable if you have intrusive persistence logic, i.e. your persisted
objects are inherited from a base class with that logic build in (or has
it aggregated inside).

> I'm thinking in terms of an application layer and a data 
> layer, and some kind of mapping layer that sits between 
> those. I'd like the application layer to be a fully-fledged 
> object-oriented thing, with rich relationships between 
> objects etc. But how can I make this layer completely 
> data-layer-ignorant---or, at least as data-layer-ignorant as possible?

        you can't. data isn't read into the objects out of nothing when
you want it, you have to order some code to get it, and data isn't
written to a database when something magical happens, you have to give
the order to do so. Two simple examples of where you have to order some
code to take data-related actions which automatically tie your code to
the data service layer. 

        THat's not to say you can't hide it as much as possible. For
example, in a non-intrusive approach, you can have a persistence service
which handles persistence of objects, objects which are normal classes
and which do not inherit from special base classes. You can work with
these classes as if they are not persisted at all, but as soon as you
want to read data into them, you want to write changes back to the
database, you have to call into some persistence service, broker etc. 

        For me the big question always is: why do people want
transparent persistence while it isn't possible? An application always
relies on other libraries and functionality.

> For example: When I have a Person class in my application 
> layer, does this class need to be equipped with a method 
> Save, or can I come up with a mechanism that makes that I do 
> not have to bother about this persistence-related 
> functionality? 

        The latter is not possible, because when would that mechanism
kick in? When the object is GC'ed? How is that code then injected? A
'Save()' method requires that the persistence logic is inside the entity
object. This isn't a problem for many people, but it has drawbacks too:
you carry around the persistence logic in all tiers, so for example your
GUI team can take shortcuts and call Save() on an order while it has to
be saved by the BL code which first checks all kind things. 

> And---how do I handle scenario's in which I 
> have two Person objects living in different AppDomains that 
> both correspond to the same Person record in the database?

        You can't, unless there is a cross thread/appdomain object
awareness system which produces the objects. For example a
webservice/remoting host. And even then, it's, IMHO, impossible that
when the object Person in appdomain A is altered, the changes are seen
in appdomain B which also has a reference to the same object. 

        There is no reason for panic though. If you look at it in the
way that entities live in the database, and in memory you only hold
mirrors of these entities, (which comes down to as much stateless
programming as possible) it's more acceptable you have multiple mirrors
somehwere in memory. If you think in objects and that these have to be
saved somewhere sometime, it's much harder to accept you have multiple
instances with the same values or better: representing the same entity. 

        If only people should more think in terms of entities inside a
database than inside memory a lot of problems related to persistence of
data would go away. After all: this problem is nothing new, it's very
old: any server system with rich clients suffers from this (heck, any
database driven website suffers from this). Most of these systems solve
this problem by simply defining a mirror of an entity 'valid' the second
they read it from the ONLY central repository entities are truly shared:
the database. If another thread alters that entity after that read, it's
not of their concern. 

        You can only avoid this by locking the entity data in the
database. This is not a valid solution for a scalable application
because when do you want to lock it? When someone read it? After all, a
rich client can make changes on the entity in memory based on the read
data.

                FB

===================================
This list is hosted by DevelopMentorŪ  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 26 Jan 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to