Re: Making sense of callbacks

From: Lachlan Deck (lachlan.dec..mail.com)
Date: Tue Dec 04 2007 - 18:06:24 EST

  • Next message: Michael Gentry (JIRA): "[JIRA] Created: (CAY-932) Cancel doesn't cancel when quitting CM with a modified model"

    Hi there,

    On 29/11/2007, at 11:22 PM, Andrus Adamchik wrote:

    > On Nov 29, 2007, at 10:56 AM, Aristedes Maniatis wrote:
    >
    >>> * prePersist() is only useful as a place to set object attributes
    >>> (such as creationDate) since you cannot follow relations reliably
    >>> in a ROP environment.
    >
    > True, and a workaround would be to support relationships for
    > transient objects. Something Kevin was bringing up on multiple
    > occasions.

    Yeah the prePersist on server (from ROP commit) would just give you a
    chance to initialise things that the client is unaware of I would've
    thought.

    Otherwise, there are no relationships to follow, really... as they've
    not been initialised yet. i.e., it's a new object that's being
    initialised / inserted into a context. The fact that you see the
    attributes already populated on server when committing from the
    client is because the prePersist in 3 tier on server is really a
    second constructor (or third). i.e., in the real java constructor you
    do nothing because the object has not as yet been inserted into an
    editing context, in prePersist on client you initialise attributes/
    relationships, in prePersist on server, you can initialise other
    stuff if needed... but you don't yet have in view the object as it
    was on the client (i.e., relationships aren't faulted).

    That fulfils most general cases.

    >>> * postUpdate() and postPersist() are useful for changes which do
    >>> not need to be committed atomically with the original commit. So
    >>> good for creating log records, but not ideal for updating
    >>> invoiceOwing.
    >
    > Another way to go about atomic commits is to set up a manual
    > transaction that spans a request scope. I think that's an
    > appropriate solution.

    Making such changes in another context (in post[Persist|Update|
    Remove]) seems like reasonable practice, the question is when will
    such changes be reflected in the former context.

    >>> * postPersist() is badly named. It is really postInsert()
    >>> * we need preInsert()
    >
    > per JPA "persist" is "insert", so the naming is correct if somewhat
    > confusing.

    Hmm. Yeah I don't think it's badly named either. It's the
    counterpart, prePersist, that doesn't match conceptually (as with
    preUpdate) in terms of when it is fired. The point is that we're
    missing (logically) a callback.

    i.e., there does need to be a callback that prePersist currently
    provides for when objects are initiated, but there's no complimentary
    callback to preUpdate for those new objects just prior to commit.
    Perhaps the JPA assumes you'll initiate your objects as per normal
    Java via Constructors and such whereas in Cayenne you don't touch the
    object until it's been inserted into a Context and thus the current
    prePersist is your constructor.

    >> * if preUpdate() is just for existing records we still need a
    >> preInsert().
    >
    > I wonder if we should just call "preUpdate" for new objects in
    > addition to prePersist.

    That doesn't sound like a nice fit. i.e., they're currently in nice
    pairs like:
    preUpdate --> postUpdate
    preRemove --> postRemove

    It would seem (to me at least), then, that you'd want (fired at the
    same times as above):
    prePersist --> postPersist

    And replace current prePersist with something like postNew or
    postCreate or something.

    So calling preUpdate would be better than nothing, if you're
    constrained by the JPA, but doesn't seem like the clean solution FWIW.

    What do you think?

    with regards,

    --
    

    Lachlan Deck



    This archive was generated by hypermail 2.0.0 : Tue Dec 04 2007 - 18:07:10 EST