Re: Reconciling DataContexts

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Tue Oct 16 2007 - 03:06:58 EDT

  • Next message: Andrus Adamchik: "Preparing 3.0M2"

    BTW, note that JPA "merge" returns a merged object, so it is exactly
    like "localObject" in that it locates a copy of an object local to
    the context.

    Andrus

    On Oct 16, 2007, at 10:02 AM, Andrus Adamchik wrote:
    > Hi Kevin,
    >
    > Relating (as in "creating a direct reference in a Java sense") two
    > objects belonging to two distinct contexts breaks fundamental
    > Cayenne design, most notably assumptions about uniquing and
    > transaction boundaries. I am -1 on that until somebody persuades me
    > that this is a good idea and explains how to avoid messing up
    > existing assumptions. (FWIW there is a workaround - referencing a
    > peer of a given object in another context via 'localObject').
    >
    >
    > On the other hand the inability to relate two TRANSIENT objects
    > (i.e. objects without a context) is indeed a shortcuming. Here is
    > one way how it might work (following the JPA patterns) :
    >
    > When such relationship is established, we would not attempt to
    > create a reverse relationship (something that would require an
    > EntityResolver to be present). We just create it one-way. So a user
    > can build an object graph of an arbitrary size without a context
    > and then at some point do one of the following with it:
    >
    > * "ObjectContext.registerNewObject(..)" (existing; equivalent to
    > JPA "persist" method)
    > * "ObjectContext.aNewMethod(..)" (does not exist yet; equivalent to
    > JPA "merge" method and somewhat of an equivalent of a "localObject"
    > method).
    >
    > Both would traverse a graph of transient objects (since they are
    > not persistent yet, the graph is assumed to be finite and will not
    > trigger sucking the entire DB in memory), attach them to the
    > context and connect missing reverse relationships. The difference
    > is that in the first case we'd assume that the objects are not yet
    > persistent, while in a second case we'd attempt to match them
    > against existing DB rows. (a typical use of a second case would be
    > receiving XML-serialized stream of objects corresponding to the
    > existing data).
    >
    >
    > But you have something different in mind? Could you elaborate on
    > the use cases?
    >
    > Thanks
    > Andrus
    >
    >
    > On Oct 16, 2007, at 1:25 AM, Kevin Menard wrote:
    >> So, if there is one thing that drives me nuts about Cayenne, it's
    >> managing
    >> ObjectContexts. In particular, you cannot relate two Persistent
    >> objects
    >> without first putting them into an ObjectContext. If one is
    >> committed and
    >> the other is not, you can have them in different contexts, but for
    >> newly
    >> created objects, this is a major pain in the neck.
    >>
    >> Since I've been complaining about it for probably close to three
    >> years now,
    >> I'd like to finally do something about it.
    >>
    >> Here are my rough notes from the airport:
    >>
    >> OK Cases:
    >>
    >> - Objects in same context
    >> - Objects in different contexts, but objects are committed already
    >>
    >> Don't work, but should:
    >>
    >> - Objects in null contexts
    >> - Objects in different contexts, but same data maps and domains
    >>
    >> Very hard to say, probably okay if don't work:
    >>
    >> - Objects in different contexts, contexts have different data maps
    >> - Objects in different contexts, contexts have different data domains
    >>
    >>
    >> As I started actually digging into the code, I ran into a lot of
    >> NPE issues
    >> trying to associate two Persistent objects with no context with
    >> one another.
    >> In an attempt to prevent adding special null-logic handling, I
    >> thought about
    >> applying the Null Object pattern to the problem. The basic idea
    >> is rather
    >> than use null as the default objectContext for CDO, use an
    >> instance of
    >> DelayedContext. The problem here is having objects in different
    >> contexts.
    >> So, it appears by fixing one, you can essentially fix the other.
    >>
    >> To address the latter, I was looking to have a Set of
    >> ObjectContexts stored
    >> in either BaseContext or DataContext. When willConnect() is
    >> called, you'd
    >> have something like the following:
    >>
    >> else if (this.getObjectContext().getEntityResolver() ==
    >> object.getObjectContext().getEntityResolver()) {
    >> ((DataContext)
    >> this.getObjectContext()).addContextToMergeWith
    >> (object.getObjectContext());
    >> ((DataContext)
    >> object.getObjectContext()).addContextToMergeWith
    >> (this.getObjectContext());
    >> }
    >> else {
    >> throw new CayenneRuntimeException(
    >> "Cannot set object as destination of
    >> relationship "
    >> + relationshipName
    >> + " because it is in a different
    >> DataMap or
    >> DataDomain.");
    >> }
    >>
    >> (Casts are just an artifact of me screwing around).
    >>
    >> What I'm thinking would happen is that when commitChanges() is
    >> called, the
    >> set of contexts to be merged with will be iterated and any changes
    >> applied
    >> to the current object store / object store graph diff. The
    >> relationship is
    >> bidirectional so that the user can initiate the commit from any
    >> object
    >> registered with any context.
    >>
    >> Here is about where I lose it. I'm not as well-versed in the
    >> internal
    >> going-ons of Cayenne as I would like to be. It appears Cayenne
    >> goes to
    >> great efforts to essentially cache the graph manipulations so as
    >> to avoid a
    >> full traversal. I really don't know, though.
    >>
    >> Caching ordering of operations could make this tricky, but in
    >> principal
    >> should be wholly doable.
    >>
    >> If anyone has any thoughts on this or can fill in any missing
    >> pieces, I'd
    >> appreciate it. This is really something I'd like to see fixed
    >> sooner rather
    >> than later. I think it may be a requisite for JPA compliance as
    >> well.
    >>
    >> --
    >> Kevin
    >>
    >>
    >
    >



    This archive was generated by hypermail 2.0.0 : Tue Oct 16 2007 - 03:07:42 EDT