Question

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

Was it helpful?

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();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top