FAQ
Nested context on ROP proposal

Preface
CayenneContext definitely misses functionality avaliable for DataContext -
nested (child) contexts. This is a description of how to implement the
feature.

Functionality
It must be logically the same as DataContext's nested contexts. Main API
usage methods are:
-creation of nested context -> ObjectContext.createChildObjectContext.
-committing changes to parent Cayennecontext ->
ObjectContext.commitChangesToParent()
-committing changes to all context tree, likely until DataContext and
underlying database -> ObjectContext.commitChanges()
-rolling back current changes -> ObjectContext.rollbackChanges and
ObjectContext.rollbackChangesLocally().

Changes should go:
-from child to parent -> through DataChannel API
-from parent to child -> through EventManager API

Once again, feature should work same as via
DataContext.createChildDataContext(), so I will not describe it here more
in detail

API changes (possibly incomplete list)
Important note here is that all changes are only increasing method's
visibility or moving them from inherited class to superclass, so no user's
code will break.
New classes/ifaces:
none. all required classes are already in Cayenne.

Method changes/additions (all in ObjectContext, BaseContext, DataContext and
CayenneContext):
ObjectContext ObjectContext.createChildObjectContext() - new method, creates
and returns a new child ObjectContext. DataContext implementation calls
createChildDataContext()
DataContext DataContext.createChildDataContext() - needs deprecation,
previous method should be used instead. This is just another step to
unification Data- and Cay- contexts
BaseContext - to implement DataChannel, because both descendants need that
API. DataContext already has implementation.
EventManager getEventManager() impl is same for both contexts and should be
moved to BaseContext
QueryResponse CayenneContext.onQuery(ObjectContext context, Query query)
should be made public since now CayenneContext supports dataChannel API

public GraphDiff DataContext.onSync(ObjectContext originatingContext,
GraphDiff changes, int syncType) method should be moved from DataContext to
BaseContext
GraphDiff DataContext.onContextRollback(ObjectContext originatingContext) -
method used by previous method, also should be moved up
GraphDiff DataContext.onContextFlush(ObjectContext originatingContext,
GraphDiff changes, boolean cascade) - should be moved up to BaseContext and
made protected and abstract, because implementations will differ.

void DataContext.fireDataChannelCommitted(Object postedBy, GraphDiff
changes)
void DataContext.fireDataChannelRolledback(Object postedBy, GraphDiff
changes)
void DataContext.fireDataChannelChanged(Object postedBy, GraphDiff changes)
- now used by both contexts, so should be moved up to BaseContext and made
protected
boolean ObjectContext.hasChanges() - returns true if there are any modified,
deleted or new objects registered with this ObjectContext. This is useful
method to add to ObjectContext. dataContext already has implementation.

/**
* "Invalidates" a Collection of persistent objects. This operation would
remove each
* object's snapshot from cache and change object's state to HOLLOW. On the
next
* access to this object, it will be refetched.
*
* @see RefreshQuery
*/
void ObjectContext.invalidateObjects(Collection objects) - another useful
method from dataContext that should be added to ObjectContext


Obsolete method - void CayenneContextGraphManager.send(GraphDiff diff,
EventSubject subject, Object eventSource) now replaced by calls to
fireDataChannel* methods described above and can be removed. It is
package-private so no user's code should break.

Tests
Everything's quite simple with junits here because dataContext's nested
contexts already have full suite of tests. All we need is to convert them to
client classes.


I'm really looking for some feedback. I think this feature is must-have for
Cayenne and I'll need it in my work

Thanks,
Andrey

Search Discussions

  • Aristedes Maniatis at Oct 24, 2008 at 8:13 am

    On 24/10/2008, at 6:27 PM, Andrey Razumovsky wrote:

    I'm really looking for some feedback. I think this feature is must-
    have for
    Cayenne and I'll need it in my work
    If you were closer I'd give you a hug. Your ideas on the surface look
    great.

    Would committing a nested context on the client cause a connection to
    be made to the server and lifecycle events, validation run on the
    server for objects in that context? If so, will changes which are made
    by lifecycle events (eg. new objects created) be propagated to the
    client (which currently doesn't happen) so they can be included in the
    parent context when it is then committed?

    Or do they remain purely on the client until the parent context is
    committed? In that case, what happens if the server validation fails
    for objects in the child context?

    Ari



    -------------------------->
    ish
    http://www.ish.com.au
    Level 1, 30 Wilson Street Newtown 2042 Australia
    phone +61 2 9550 5001 fax +61 2 9550 4001
    GPG fingerprint CBFB 84B4 738D 4E87 5E5C 5EFA EF6A 7D2E 3E49 102A
  • Andrey Razumovsky at Oct 24, 2008 at 9:03 am


    Would committing a nested context on the client cause a connection to be
    made to the server and lifecycle events, validation run on the server for
    objects in that context? If so, will changes which are made by lifecycle
    events (eg. new objects created) be propagated to the client (which
    currently doesn't happen) so they can be included in the parent context when
    it is then committed?

    Or do they remain purely on the client until the parent context is
    committed? In that case, what happens if the server validation fails for
    objects in the child context?

    Nested context idea specifies that changes should be purely on the client.
    Otherwise we lose ability to commitChangesToParent()
    Client nested context is normal CayContext, just with another DataChannel,
    (i.e. source to commit changes to). So validation works *on client* within
    context which called commitChanges(). Changes to server (with server
    validation & lifecycles) will proceed through all context hierarchy if you
    call CayenneContext.commitChanges(),
    not CayenneContext.commitChangesToParent(). That's just the same as with
    DataContext, I haven't invented anything new.
    As you correctly pointed out, problem occurs with the following sequence:
    1. Nested CayContext [with incorrect changes] is committed to parent.
    Validation on nested client context succeeds
    2. Parent context is committed to server. Validation on client context
    succeeds since it did in #1
    3. Server validation fails. Parent context changes are rolled back.
    By default in nested context they do not.

    Right now I cannot think of ideal solution.
    At the minimum we could just do nothing and hope that server validation will
    succeed if client did.
    We could check objects before committing to parent (i.e. do 'false' commit
    to server), but I'm afraid that'll be too expensive.
    Or we could send notification to children if parent commit failed, but this
    is quite unnatural to make changes in child context behind the scenes.
    Would be great if we together thought about it

    Andrey
  • Lachlan Deck at Nov 11, 2008 at 11:20 am

    On 24/10/2008, at 8:02 PM, Andrey Razumovsky wrote:

    Would committing a nested context on the client cause a connection
    to be
    made to the server and lifecycle events, validation run on the
    server for
    objects in that context? If so, will changes which are made by
    lifecycle
    events (eg. new objects created) be propagated to the client (which
    currently doesn't happen) so they can be included in the parent
    context when
    it is then committed?

    Or do they remain purely on the client until the parent context is
    committed? In that case, what happens if the server validation
    fails for
    objects in the child context?
    Nested context idea specifies that changes should be purely on the
    client. Indeed.
    Otherwise we lose ability to commitChangesToParent()
    Client nested context is normal CayContext, just with another
    DataChannel,
    (i.e. source to commit changes to).
    So validation works *on client* within
    context which called commitChanges(). Changes to server (with server
    validation & lifecycles) will proceed through all context hierarchy
    if you
    call CayenneContext.commitChanges(),
    not CayenneContext.commitChangesToParent().
    What would the behaviour be for a non-nested context on client calling
    commitChangesToParent()?
    That's just the same as with
    DataContext, I haven't invented anything new. sure.
    As you correctly pointed out, problem occurs with the following
    sequence:
    1. Nested CayContext [with incorrect changes] is committed to parent.
    Validation on nested client context succeeds
    That seems normal. I mean currently during commit validation is only
    run on the server assuming success on client (where the server is like
    the parent). So it'll be the responsibility of the programmer to
    handle this.
    2. Parent context is committed to server. Validation on client context
    succeeds since it did in #1
    3. Server validation fails. Parent context changes are rolled back.
    By default in nested context they do not.

    Right now I cannot think of ideal solution.
    At the minimum we could just do nothing and hope that server
    validation will
    succeed if client did.
    Yeah - that's fragile.
    We could check objects before committing to parent (i.e. do 'false'
    commit
    to server), but I'm afraid that'll be too expensive.
    Don't see this is necessary besides being expensive. This would be
    better served by allowing server/client classes to utilise a business
    logic shared static helper that can be shared between the server/
    client classes to perform validation against.
    Or we could send notification to children if parent commit failed,
    but this
    is quite unnatural to make changes in child context behind the scenes.
    Would be great if we together thought about it

    Andrey
    with regards,
    --

    Lachlan Deck
  • Andrey Razumovsky at Nov 11, 2008 at 12:12 pm
    Thanks for your answer

    So validation works *on client* within
    context which called commitChanges(). Changes to server (with server
    validation & lifecycles) will proceed through all context hierarchy if you
    call CayenneContext.commitChanges(),
    not CayenneContext.commitChangesToParent().
    What would the behaviour be for a non-nested context on client calling
    commitChangesToParent()?

    I guess that should be same as with DataContext - normal commit to database.
    Upper level is DB after all.

    That's just the same as with
    DataContext, I haven't invented anything new.
    sure.

    As you correctly pointed out, problem occurs with the following sequence:
    1. Nested CayContext [with incorrect changes] is committed to parent.
    Validation on nested client context succeeds
    That seems normal. I mean currently during commit validation is only run on
    the server assuming success on client (where the server is like the parent).
    So it'll be the responsibility of the programmer to handle this.

    2. Parent context is committed to server. Validation on client context
    succeeds since it did in #1
    3. Server validation fails. Parent context changes are rolled back.
    By default in nested context they do not.

    Right now I cannot think of ideal solution.
    At the minimum we could just do nothing and hope that server validation
    will
    succeed if client did.
    Yeah - that's fragile.

    We could check objects before committing to parent (i.e. do 'false' commit
    to server), but I'm afraid that'll be too expensive.
    Don't see this is necessary besides being expensive. This would be better
    served by allowing server/client classes to utilise a business logic shared
    static helper that can be shared between the server/client classes to
    perform validation against.

    Are you suggesting developers to keep same validation on client & server in
    this case? Well, this means that we prefer first solution - to do nothing
    :-) Actually I can think of situations when special server validation is
    needed - e.g. when it takes long time and will be much longer via ROP.
    Still, I agree and think we should leave this as 'known limitation'.
    In fact, beside this problem, I've already implemented nested contexts and
    hopefully will commit after M5 is released.

    Cheers,
    Andrey
  • Lachlan Deck at Nov 11, 2008 at 12:34 pm

    On 11/11/2008, at 11:12 PM, Andrey Razumovsky wrote:

    Are you suggesting developers to keep same validation on client &
    server in
    this case? Well, this means that we prefer first solution - to do
    nothing
    :-) Easy ;-)
    Actually I can think of situations when special server validation is
    needed - e.g. when it takes long time and will be much longer via ROP.
    Additionally when for security reasons it only makes sense on the
    server.
    Still, I agree and think we should leave this as 'known limitation'.
    In fact, beside this problem, I've already implemented nested
    contexts and
    hopefully will commit after M5 is released.
    Great.

    with regards,
    --

    Lachlan Deck
  • Aristedes Maniatis at Nov 11, 2008 at 12:42 pm

    On 11/11/2008, at 11:12 PM, Andrey Razumovsky wrote:

    Are you suggesting developers to keep same validation on client &
    server in
    this case? Well, this means that we prefer first solution - to do
    nothing
    :-) Actually I can think of situations when special server
    validation is
    needed - e.g. when it takes long time and will be much longer via ROP.
    Absolutely we need to be able to keep them separate. Sometimes. But
    because client and server entity classes aren't in the same
    inheritance tree, it is really hard to share the 90% of validation
    code which is identical.

    In our application, we validate on each keystroke, allowing us to
    enable/disable the save button and implement nice GUI warnings.
    Obviously this needs to be really fast on the client. And so there is
    more validation on the server which does not exist on the client. But
    we've been bitten sometimes by not keeping the two in sync where they
    should be.

    Still, I agree and think we should leave this as 'known limitation'.
    In fact, beside this problem, I've already implemented nested
    contexts and
    hopefully will commit after M5 is released.
    Terrific! I can definitely say we'll be able to give it a solid
    workout here.


    Andrey, you might like to add the special limitations to be aware of
    on this page and a note about it being available in M6:

    http://cwiki.apache.org/confluence/display/CAYDOC/Nested+DataContexts

    I know it is slightly premature, but I'm very excited :-)


    Ari



    -------------------------->
    ish
    http://www.ish.com.au
    Level 1, 30 Wilson Street Newtown 2042 Australia
    phone +61 2 9550 5001 fax +61 2 9550 4001
    GPG fingerprint CBFB 84B4 738D 4E87 5E5C 5EFA EF6A 7D2E 3E49 102A
  • Andrey Razumovsky at Dec 8, 2008 at 10:16 am
    Okay, M5 is now branched, and if noone has objections on API changes, I will
    soon commit

    2008/11/11, Aristedes Maniatis <ari@ish.com.au>:

    On 11/11/2008, at 11:12 PM, Andrey Razumovsky wrote:

    Are you suggesting developers to keep same validation on client & server in
    this case? Well, this means that we prefer first solution - to do nothing
    :-) Actually I can think of situations when special server validation is
    needed - e.g. when it takes long time and will be much longer via ROP.
    Absolutely we need to be able to keep them separate. Sometimes. But because
    client and server entity classes aren't in the same inheritance tree, it is
    really hard to share the 90% of validation code which is identical.

    In our application, we validate on each keystroke, allowing us to
    enable/disable the save button and implement nice GUI warnings. Obviously
    this needs to be really fast on the client. And so there is more validation
    on the server which does not exist on the client. But we've been bitten
    sometimes by not keeping the two in sync where they should be.


    Still, I agree and think we should leave this as 'known limitation'.
    In fact, beside this problem, I've already implemented nested contexts
    and
    hopefully will commit after M5 is released.
    Terrific! I can definitely say we'll be able to give it a solid workout
    here.


    Andrey, you might like to add the special limitations to be aware of on
    this page and a note about it being available in M6:

    http://cwiki.apache.org/confluence/display/CAYDOC/Nested+DataContexts

    I know it is slightly premature, but I'm very excited :-)


    Ari



    -------------------------->
    ish
    http://www.ish.com.au
    Level 1, 30 Wilson Street Newtown 2042 Australia
    phone +61 2 9550 5001 fax +61 2 9550 4001
    GPG fingerprint CBFB 84B4 738D 4E87 5E5C 5EFA EF6A 7D2E 3E49 102A

  • Andrus Adamchik at Dec 8, 2008 at 3:10 pm
    Please go ahead. Trunk is open for new development for a couple of
    weeks now.

    Cheers,
    Andrus
    On Dec 8, 2008, at 12:16 PM, Andrey Razumovsky wrote:

    Okay, M5 is now branched, and if noone has objections on API
    changes, I will
    soon commit

    2008/11/11, Aristedes Maniatis <ari@ish.com.au>:

    On 11/11/2008, at 11:12 PM, Andrey Razumovsky wrote:

    Are you suggesting developers to keep same validation on client &
    server in
    this case? Well, this means that we prefer first solution - to do
    nothing
    :-) Actually I can think of situations when special server
    validation is
    needed - e.g. when it takes long time and will be much longer via
    ROP.
    Absolutely we need to be able to keep them separate. Sometimes. But
    because
    client and server entity classes aren't in the same inheritance
    tree, it is
    really hard to share the 90% of validation code which is identical.

    In our application, we validate on each keystroke, allowing us to
    enable/disable the save button and implement nice GUI warnings.
    Obviously
    this needs to be really fast on the client. And so there is more
    validation
    on the server which does not exist on the client. But we've been
    bitten
    sometimes by not keeping the two in sync where they should be.


    Still, I agree and think we should leave this as 'known limitation'.
    In fact, beside this problem, I've already implemented nested
    contexts
    and
    hopefully will commit after M5 is released.
    Terrific! I can definitely say we'll be able to give it a solid
    workout
    here.


    Andrey, you might like to add the special limitations to be aware
    of on
    this page and a note about it being available in M6:

    http://cwiki.apache.org/confluence/display/CAYDOC/Nested+DataContexts

    I know it is slightly premature, but I'm very excited :-)


    Ari



    -------------------------->
    ish
    http://www.ish.com.au
    Level 1, 30 Wilson Street Newtown 2042 Australia
    phone +61 2 9550 5001 fax +61 2 9550 4001
    GPG fingerprint CBFB 84B4 738D 4E87 5E5C 5EFA EF6A 7D2E 3E49 102A

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupdev @
categoriescayenne
postedOct 24, '08 at 7:28a
activeDec 8, '08 at 3:10p
posts9
users4
websitecayenne.apache.org

People

Translate

site design / logo © 2022 Grokbase