Re: Reconciling DataContexts

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Sat Oct 20 2007 - 04:36:40 EDT

  • Next message: Andrus Adamchik: "Re: Trunk failing to build"

    On Oct 19, 2007, at 10:58 PM, Kevin Menard wrote:

    > So, looking at the problem again, I see a few issues with
    > localObject():
    >
    > 1) Overly verbose syntax. Consider:
    >
    > a.setSomething(b);
    >
    > versus
    >
    > a.setSomething((BType) a.getObjectContext().localObject
    > (b.getObjectId(),
    > b));
    >
    > I think this can largely be addressed by adding a new case to
    > willConnect(), though. If the contexts are different, look at the
    > persistence state and call localObject() automatically if it makes
    > sense to.
    > This helps ease up on the transparency issues as well. Rather than
    > using
    > one method for new, unregistered objects (setXXX()) and another for
    > committed, registered objects (localObject()), you can consolidate
    > to just
    > the setter.

    I think actually the suggested terse syntax is more confusing on a
    number of levels:

    * normally a user would assume that after "a.setSomething(b)",
    "b.getSomethingElse() == a" (i.e. the reverse relationship is set),
    which would not be the case as reverse is set for the clone of "b".
    * and on a higher level it would obscure the fact that cross-context
    relationships are not possible by design.

    I.e. I think explicit is good in this case. Also with JDK 1.5 switch
    we can remove the need for casts in many situations, making current
    approach less verbose.

    > 2) Loss of transient values.
    >
    > This could probably be addressed reflectively.

    True. Also JPA introduces explicit "transient" attributes - something
    we can use to address this issue.

    > 3) Growth of object store.
    >
    > This is trickier. Ideally, if I call setSomething(a) with 50
    > different
    > instances of a, the object store would only have the latest a,
    > since that's
    > the only one that's going to be committed. What you have instead
    > is 50
    > different instances. With caching, I don't think DB access is the
    > issue,
    > but you will have an unbounded memory issue.

    I wouldn't worry about that in 3.0 - ObjectStore is using weak
    references now, so if you don't have a hard reference in the user
    code, the object will be gc'd as needed.

    > By hiding this in a setter, it may be possible to unregister
    > the old
    > object first, thereby limiting the growth.

    Not a good idea. Consider this:

    1: BType blocal = (BType) a.getObjectContext().localObject
    (b.getObjectId(), b);
    2: a.setSomething(blocal );
    3: a.setSomething( (BType) a.getObjectContext().localObject
    (b1.getObjectId(), b1));
    4. blocal.doSomething();

    "blocal" will be kicked out of the a's context in line 3, but the
    user already referenced this object in line 1, so when he later
    accesses it on line 4, it is no longer persistent. As I mentioned
    above there's no problem anymore with unused object accumulation, and
    generally trying to second-guess Cayenne on object graph management
    may cause undesired side effects.

    Andrus



    This archive was generated by hypermail 2.0.0 : Sat Oct 20 2007 - 04:37:17 EDT