Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine which properties of a RESTful resource have changed before save when using Spring Data REST repositories?

If I have the following resource published by Spring Data REST...

{ "status": "idle" }

How could I react to a PATCH or PUT that changes the value of property status? The idea would be to trigger some server process based on a property change.

Ideally this would happen before save and it would be possible to compare the new version of the resource with the previously-persisted version.

like image 860
Gabriel Bauman Avatar asked Nov 02 '25 06:11

Gabriel Bauman


1 Answers

You would usually use a @RepositoryEventHandler to hook up your event logic - see the documentation for details.

I do not know of a function to directly get the changed properties. But if you use a HandleBeforeSave handler you can load the persistent entity (old state) and compare it against the new state -

    @RepositoryEventHandler 
    @Component
    public class PersonEventHandler {

      ...

      @PersistenceContext
      private EntityManager entityManager;

      @HandleBeforeSave
      public void handlePersonSave(Person newPerson) {
        entityManager.detach(newPerson);
Person currentPerson = personRepository.findOne(newPerson.getId());
        if (!newPerson.getName().equals(currentPerson.getName)) {
          //react on name change
        }
       }
    }

Note that you need to detach the newPerson from the current EntityManager. Otherwise we would get the cached person object when calling findOne - and we could not compare to the updated version against the current database state.

Alternative if using Eclipselink

If you are using eclipselink you can also find out the changes that have been applied to your entity in a more efficient fashion avoiding the reload - see here for details

        UnitOfWorkChangeSet changes = entityManager.unwrap(UnitOfWork.class).getCurrentChanges();
        ObjectChangeSet objectChanges = changes.getObjectChangeSetForClone(newPerson);
        List<String> changedAttributeNames = objectChanges.getChangedAttributeNames();
        if (objectChanges.hasChangeFor("name")) {
            ChangeRecord changeRecordForName = objectChanges.getChangesForAttributeNamed("name");
            String oldValue = changeRecordForName.getOldValue();

        }
like image 165
Mathias Dpunkt Avatar answered Nov 04 '25 22:11

Mathias Dpunkt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!