> Hi Paul,
>
> Good question, I should've mentioned that.
>
> Two DataObjects residing in peer DataContexts have no "hard" link with?
> each other. What makes them "related" is their ObjectIds.
>
> Now, when an object is updated and then committed in one DataContext,
> what happens to the peers? Peer synchronization is done via events.
> Default behavior of the peer DataContext [see
> ObjectStore.snapshotsChanged(..) method for details] is to invalidate
> all COMMITTED objects, and merge changes to the MODIFIED and DELETED
> objects. But if the same property is already modified in the peer
> object, merge process will leave it alone.
>
> If you want fine grained control over merging behavior, implement a
> DataContextDelegate:
> http://objectstyle.org/cayenne/userguide/datactxt/data-context-
> delegate.html
>
> Andrus
>
Andrus,
Thanks again for the explanation - this is what I would have expected but
for some reason in the test code (below) I dont see the peer merging. I may
have some configuration options wrong or be doing something odd but do have
shared cache enabled for the domain - any further insight would be
appreciated !
public class TestConcurrent {
public static String printState(String title, Artist r1, Artist r2) {
return title + " - [dc1] r1.name='" + r1.getArtistName() + "' "
+ "(State=" + r1.getPersistenceState() + ") / "
+ " [dc2] r2.name='" + r2.getArtistName() + "' "
+ "(State=" + r2.getPersistenceState() + ")";
}
public static void main(String[] args) {
DataContext dc1 = DataContext.createDataContext();
DataContext dc2 = DataContext.createDataContext();
LogDelegate ld1 = new LogDelegate();
ld1.setPrefix(">>> (DC1) Delegate");
dc1.setDelegate(ld1);
LogDelegate ld2 = new LogDelegate();
ld2.setPrefix(">>> (DC2) Delegate");
dc2.setDelegate(ld2);
// Create Test Record
Artist a1 = (Artist) dc1.createAndRegisterNewObject(Artist.class);
a1.setArtistName("Original");
dc1.commitChanges();
Expression qual = Expression.fromString("artistName = 'Original'");
SelectQuery query = new SelectQuery(Artist.class,qual);
List result1 = dc1.performQuery(query);
List result2 = dc2.performQuery(query);
// Skip error check for the moment
Artist r1 = (Artist) result1.get(0);
Artist r2 = (Artist) result2.get(0);
System.out.println(printState("--- Initial Load ",r1,r2));
r1.setArtistName("Changed in DC1");
System.out.println(printState("--- Update in DC1",r1,r2));
dc1.commitChanges();
System.out.println(printState("--- Commit in DC1",r1,r2));
}
}
(LogDelegate is DataContextDelegate which just logs the delegate methods)
When I run this I get the following:
>>> (DC1) Delegate:willPerformSelect - org.objectstyle.cayenne.query.SelectQuer..d4c49
>>> (DC2) Delegate:willPerformSelect - org.objectstyle.cayenne.query.SelectQuer..d4c49
--- Initial Load - [dc1] r1.name='Original' (State=3) / [dc2] r2.name='Original' (State=3)
--- Update in DC1 - [dc1] r1.name='Changed in DC1' (State=4) / [dc2] r2.name='Original' (State=3)
--- Commit in DC1 - [dc1] r1.name='Changed in DC1' (State=3) / [dc2] r2.name='Original' (State=3)
It doesnt look like the delegate mergeChanges methods are being called
and the object in dc2 is stale.
Paul
This archive was generated by hypermail 2.0.0 : Wed Jun 09 2004 - 11:34:21 EDT