Quoting Shane Mingins <[EMAIL PROTECTED]>:
> 
> Yes it does :-) And answered more.  Thanks.  I am currently developing a
> Struts/OJB app and have not yet nutted out the architectural issues/design
> ... have been reading Core J2EE Patterns and Patterns of Enterprise
> Application Architecture.
> 
> OJB caches a read object so that I do not wish to pass that actual 
instance
> up to the View layer for editing ....IOW that instance only changes when 
an
> updated version is persisted.   So in essence I need to create a session
> copy of my domain model from its persisted state to be available for 
editing
> (business transactions).  But as this is a object with a collection of 
other
> editable objects it seems that creating a type of Value Object or session
> copy is not that trivial.

What I do is retrieve a fresh version of the object with each command. A 
typical Command begins like:
<code>
public static Map execute() throws CommandException
{
    if (!validate()) return this.errors; // validate populates errors
    try
    {
        Unit unit = BaseRepository.beginUnit();
        User user = UserRepository.findById(this.getUserId(), unit);
        User friend = UserRepository.findById(this.getFriendId(), unit);
        Request request = user.requestFriend(friend);
        unit.commit()
    catch (PersistenceException e)
    {
        throw new CommandError("Unable to request friend: " +
                                 e.getMessage(), e);
    } 
    Map results = new HashMap();
    if (request == null)
    {
        this.errors = new ArrayList();
        this.errors.add(this.UNKNOWN_ERROR);  
    }
    else
    {
        results.put(this.REQUEST, request);
    }
    results.put(this.USER, user);
    results.put(this.FRIEND, friend);
    return results;
}
</code>
The Unit provides a transaction wrapper, the *Repository classes provide 
querying. They can do OQL, but the byId(...) type query is optimized to hit 
the cache by creating an ObjectIdentity and querying by identity, so it is 
preferred.

Once the object is outside of the Transaction changes you make to it are not 
propogated down to the database. In my particular case (well not for my toy 
app, but for the larger app the toy is a spike for) anyway. I need to check 
what happens to the cached version if you make changes on the non-
transactional persistent object. As I *don't* anywhere it isn't a problem 
for me, but I am not confident of the behavior of the cache for non-
transactional versions. Am thinking of two solutions

1) A Cache implementation that only provides java object identity ( = ) 
within a single transaction boundary. I am not sure how this would work, may 
have to hack around some. Cache might clone the object and return the clone 
within transactional boundaries, but I am not sure the cache can detect 
transactions. Maybe use cglib to return a derived proxy that handles things. 
Hmmm. Must go poke when I have a chance.

2) Changing my code generator to go back to an old idea of generating a 
getter-only interface for the data containers. I generate a base impl of 
each persistent class with just the persistent fields and derive from it for 
all logical stuff. This makes for handy-dandy transfer objects, etc. Back 
when I started thinking about it i considered generating the base impl, a 
getter, and a getter/setter interface specifically for this. i didn't wind 
up going with it as I decided that was just overkill, I trust the developers 
I work with. Cache behaviour could be an issue though. Must go write some 
learning tests.

Anyway...

A side effect is that I can plug ODMG, OTM, and other (am thinking of doing 
a Hibernate implementation for shits and giggles -- it claims to support OQL 
as a subset of HQL so all my query string should still work as-is) 
persistence mechanisms very easily. Right now I swap out ODMG and OTM 
regularly as I am using this project to get familiar with the OTM.

-Brian

-------------------------------------------------
This mail sent through IMP: http://horde.org/imp/


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to