Search code examples
apache-cayenne

what is the current best method of getting the changes to an object hierarchy in Apache Cayenne?


I am evaluating Cayenne for some new projects.

I wonder if it is possible (for unit test assertions) to capture changes the tested code did to an ObjectContext (or some underlying data representation) preferably before the commitChanges method being called, and what is the best practice for it? I am interested in enumerating to-be-updated/to-be-inserted/to-be-deleted objects or rows and for to-be-updated objects or rows I am also interested on what attributes/columns actually changed?


Solution

  • Change tracking in Cayenne can be done at a number of levels:

    1. The most user-friendly and comprehensive API for capturing before and after "deltas" is provided by cayenne-commitlog, but it only works during commit.

    2. Finding "dirty" objects in the context at any time before commit is done via ObjectContext.uncommittedObjects(), ObjectContext.newObjects(), ObjectContext.deletedObjects(), ObjectContext.modifiedObjects().

    3. If you want to dig deeper with #2, and track individual changes to objects before commit, you may look at ObjectStore, though this API is for internal framework use, so it requires some jumping through hoops. There's definitely room for improvement on Cayenne side:

    ObjectStore os = (ObjectStore) context.getGraphManager();
    
    // get DB snapshot of an object that can be compared with the object current state
    DataRow previousState = os.getSnapshot(o.getObjectId());
    
    // also there's a full diff available, but unfortunately "getChanges" is package-private,
    // so can only be accessed via some reflection hacks (or a custom utility class placed 
    // in "org.apache.cayenne.access" package). 
    // Cayenne should make it public in the future I think.
    GraphDiff diff = os.getChanges();
    diff.apply(myChangeTrackingVisitor);