> 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