Thank you Maik.

I was hoping for something much simpler than this and that's baked into Cayenne.


On 2019-01-22 11:19 a.m., Maik Musall wrote:
Hi Andrew,

I did it like this in a DataDomainListener:

        @PreUpdate( { CayenneDataObject.class } )
        public void handleBeforeUpdateHook( CayenneDataObject object ) {
                if( object instanceof BeforeSaveHook ) {
                        ((BeforeSaveHook)object).beforeSaveAction();
                }
        }

and then have BeforeSaveHook be an interface, and then implementing 
beforeSaveAction in the DataObject classes. To get the actual changes, I also 
didn't find anything handy, and ended up doing it like this (in my custom 
DataObject subclass):

        public Map<String,ValueDifference<Object>> changedAttributes() {
                Set<String> attributeKeys = new HashSet<>( attributeKeys() );
                Map<String,Object> dataRow = oc().getObjectStore().getSnapshot( 
getObjectId() );
                
                if( dataRow == null ) { // newly inserted object
                        dataRow = new HashMap<>();
                        for( String key : attributeKeys ) {
                                dataRow.put( key, null );
                        }
                }
                
                Map<String,Object> committedValues = new HashMap<>();
                Map<String,Object> uncommittedValues = new HashMap<>();
                for( String key : dataRow.keySet() ) {
                        if( !attributeKeys.contains( key ) ) continue;
                        committedValues.put( key, dataRow.get( key ) );
                        Object uncommittedValue = readPropertyDirectly( key );
                        uncommittedValues.put( key, uncommittedValue );
                }
                
                MapDifference<String,Object> difference = Maps.difference( 
committedValues, uncommittedValues );
                Map<String,ValueDifference<Object>> entriesDiffering = 
difference.entriesDiffering();        // assuming the all keys will always be present in 
both
                return entriesDiffering;
        }


(where ValueDifference and MapDifference are Guava classes). Hope it helps, 
perhaps someone else has a better solution.

Maik



Am 22.01.2019 um 17:06 schrieb Andrew Willerding <[email protected]>:

I can't seem to find documentation, or better yet some examples for 4.0 or 4.1 
that explains how to check for either a single property change or how to get a 
list of the property changes in an onPreUpdate callback. Unless I'm missing 
something obvious (entirely likely ;-) ) the Lifecycle events documentation 
doesn't seem to mention any way to do this.  Is this something that I need to 
manually track in the application?

Also, what should I do if I want to reject the changes inside of an onPreUpdate 
callback?  Do I need to do an explicit rollback or simply throw a 
CayenneRuntimeException of some sort?  I'm guessing it's an explicit rollback.

Thanks,

Andrew




Reply via email to