Search code examples
javajakarta-eeormapache-cayenne

getting a fresh data object in Apache Cayenne


I want each action taken on certain tables to be logged. I want logging at column level (not all but some) so if a value has been changed for certain column I would like to log that for eg.

Price for product x has been changed by user U

(assume price & product are in the same table.)

for this I want to monitor price column of product x.

I cannot use a trigger to do this as I want the user to be logged as well, User information atm is the in the portal application (can't pass that to the trigger).

I am currently using apache cayenne and on the pre-update (in the entity class) call back I want to compare the new price (which the user has chosen in portal) to the one sitting in Database

when I try to get the product from database, cayenne does not returns me a fresh object, rather returns the same object with changed values

I was wondering if anyone is aware of some way Cayenne can return me fresh object for the same pk(id) (thats what I am using to get a fresh object from the db)

or

can advice me some other way


Solution

  • There are a few ways to approach this. Here is the one that IMO is the most transparent. The trick is to use a different ObjectContext from the one committing changes. Then you will get a separate copy of the object that will contain currently saved value:

    // 'this' refers to the DataObject being committed (assuming things happen in its callback)
    
    ObjectContext parallelContext = ... // create a new context here like you normally would
    
    // 3.1 API; 3.0.x has a similar method with a slightly different sig
    MyClass clone = parallelContext.localObject(this);
    
    // if you are ok with cached old value, ignore the 'invalidateObjects' call.
    // If not, uncomment it to ensure the object gets refetched. 
    // Also 3.1 API. Should be easy to adjust for 3.0
    
    // parallelContext.invalidateObjects(clone);
    
    Object oldValue = clone.getXyz();