Right. This was one of the options briefly mentioned on SO, and is *the* way to 
do it with the current public API. The downsides are of course forcing the user 
to deal with translation of names from DB space to object space, and the 
inability to track to-many relationship changes (which may not be always 
needed). 

Andrus

> On Oct 16, 2019, at 4:56 AM, Maik Musall <m...@selbstdenker.ag> wrote:
> 
> Hi Andrus,
> 
> I had a way to do this when I migrated from EOF to Cayenne and needed to keep 
> it. This is what I came up with at the time (uses Guava). It’s a method on my 
> own 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;
>       }
> 
> Not really pretty, but works and doesn’t require reflection.
> 
> Maik
> 
> 
>> Am 11.10.2019 um 12:28 schrieb Andrus Adamchik <and...@objectstyle.org>:
>> 
>> Was just answering Cayenne change tracking question on StackOverlow [1], and 
>> realized that the only user-friendly API that allows to check for individual 
>> changes is "cayenne-commitlog" that only works during commit. All the 
>> pre-commit APIs are internal and require lots of hoop jumping. I think we 
>> can address that on the cheap in 4.2 by defining a method like this in 
>> GraphManager.java:
>> 
>> GraphDiff getChanges();
>> 
>> We already have such method implemented in ObjectStore, so there's really no 
>> effort and an immediate benefit. Or take it a step further and additionally 
>> implement filtering changes per object:
>> 
>> GraphDiff getChanges(Persistent)
>> 
>> Thoughts?
>> 
>> Andrus
>> 
>> [1] 
>> https://stackoverflow.com/questions/58318730/what-is-the-current-best-method-of-getting-the-changes-to-an-object-hierarchy-in
> 

Reply via email to