ebean icon indicating copy to clipboard operation
ebean copied to clipboard

Property "old values" in BeanPersistListener#updated

Open GithubUser8080 opened this issue 1 year ago • 2 comments

Hi, i would like to ask if there is a way to retrieve the old values of updated properties in a BeanPersistListener. The set of changed properties is provided in the method, but there does not seem to be a way to get the old values. I know there is a ChangeLogListener but that does not provide the entire current bean. Is there a workaround for this? Thank you

EDIT:

The current use case is to create a listener that

  1. When Model A is updated
  2. Log all changed properties (old and new values), along with the current value of some specific properties.

GithubUser8080 avatar Sep 19 '22 10:09 GithubUser8080

For BeanPersistListener no.

For a BeanPersistController / BeanPersistAdapter yes via BeanPersistRequest.updatedValues(). That is, look to use a BeanPersistController postUpdate() instead of BeanPersistListener if you want access to that detail.

Cheers, Rob.

On Mon, 19 Sept 2022 at 22:10, GithubUser8080 @.***> wrote:

Hi, i would like to ask if there is a way to retrieve the old values of updated properties in a BeanPersistListener. The set of changed properties is provided in the method, but there does not seem to be a way to get the old values. I know there is a ChangeLogListener but that does not provide the entire current bean. Is there a workaround for this? Thank you

— Reply to this email directly, view it on GitHub https://github.com/ebean-orm/ebean/issues/2836, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABTATN7OY5WO2QHF6XX3MTV7A3YHANCNFSM6AAAAAAQP6SHFA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

rbygrave avatar Sep 19 '22 10:09 rbygrave

Thank you for the quick response! Isn't the BeanPersistController method called before commit though? Meaning, there being no way to guarantee that my custom auditing only happens in the case of a successful commit, and leading to false logs. Unless i am mistaken.

GithubUser8080 avatar Sep 19 '22 10:09 GithubUser8080

So you are either looking for either:

A) A change to ChangeLog so that a bean update has access to the bean itself B) A change to BeanPersistListener to have access to Map<String, ValuePair> updatedValues();

Is that right? Can you explain the use case more? What is needed to be read from the bean for the change log option?

rbygrave avatar Sep 27 '22 00:09 rbygrave

Yes, correctly.

One of the use cases is an auditing/logging requirement that tracks changes to accounts, but needs some standard account fields to have the full information, e.g, [account_id, account_email, old_values, new_values], or potentially send an email like "Your account username was changed from (account.oldusername) to (account.newusername)" to account.email

We worked around this by storing the Map<String, ValuePair> in a transient property and accessing it in BeanPersistListener for the moment, so no need to implement anything, thank you. Just wanted to make sure there is no "standard" way

GithubUser8080 avatar Sep 27 '22 07:09 GithubUser8080

needs some standard account fields to have the full information

Just to note that ChangeLog has:

  /**
   * Arbitrary user context information expected to be optionally populated by ChangeLogPrepare.
   */
  Map<String, String> userContext;

So for changeSet level arbitrary context information (maybe a bit like like account_id, account_email) that information is expected to go into the ChangeLog userContext map during ChangeLogPrepare.

If for this case the account_id, account_email are actually bean level userContext (which it sounds like they are) currently ChangeLog has no support for that (there is no per bean userContext map). Interesting, hmmm.

rbygrave avatar Sep 27 '22 20:09 rbygrave

Ok, I think we can close this issue for now.

We might want to reopen / revisit and come up with a more elegant solution down the track. Perhaps something like ... extend BeanPersistListener such that it states if it wants to obtain old values for updates. If it does then we obtain that during persisting and make that available later to the BeanPersistListener.

For the moment lets close this with no immediate desire to make a change here.

rbygrave avatar Oct 14 '22 02:10 rbygrave