1

I have the below JPA Entity and I would like to use the @PrePersist and @PreUpdate to facilitate the setting of the lastUpdatedBy String with the current user from the Spring context, but I don't know how I can access that information from an entity level context. Any ideas?

public abstract class BaseEntity {
  private Date createdDate;
  private String lastUpdatedBy;

    @Column(name = "LAST_UPDATED_BY")
    public String getLastUpdatedBy() {
        return lastUpdatedBy;
    }

    public void setLastUpdatedBy(String lastUpdatedBy) {
        this.lastUpdatedBy = lastUpdatedBy;
    }

  @Temporal(TemporalType.TIMESTAMP)
  @Column(name="CREATED_DATE")
  public Date getCreatedDate() {
    return createdDate;
  }

  public void setCreatedDate(Date created) {
    if (created != null) {
      this.createdDate = created;
    }
  }


  @PrePersist
  protected void onCreate() {
    createdDate = new Date();
    //lastUpdatedBy =  //need to access Spring user here
  }

 @PreUpdate
    public void onUpdate() {
      updatedDate = new Date();
      //lastUpdatedBy =  //need to access Spring user here
    }

}
c12
  • 9,557
  • 48
  • 157
  • 253
  • http://stackoverflow.com/questions/3191569/good-way-to-access-spring-singleton-from-within-domain-objects.
    But are you sure you can't do that in your `@Service` or `@Repository` in a less "hidden" way?
    – Luca Basso Ricci Aug 26 '13 at 21:48
  • @bellabax - it does seem like there are two approaches, one is JPA annotations and the other is SPRING Data annotations. – c12 Aug 26 '13 at 22:01
  • 1
    Sorry, what I meant is that this problem seems to be resolvable using a function in your DAO (like `updateXXX(BaseEntity xxx,String updateBy)`) instead of listener to be more clear about `lastUpdateBy` lifecycle and don't hide it (is an application concerns, it lives as external info respect BaseEntity). I hope to be clear, nothing to do with spring/jpa annotation – Luca Basso Ricci Aug 26 '13 at 22:10
  • @bellabax - my goal was to abstract this type of logic into the entity. Setting the user information in the service or dao layer is certainly doable. I just wondered if there was a way to do it without having to pass the updatedBy String between the layers, but it sounds like more headache than its worth – c12 Aug 26 '13 at 22:14
  • You don't mention Spring Security, but if that's how you're authenticating users you can access the user straight from the current thread using `SecurityContextHolder` ... – MattR Aug 27 '13 at 02:08
  • Not using Spring Security, but thanks for the input...helpful to those using it – c12 Aug 27 '13 at 20:24

1 Answers1

3

A solution can be the one as defined in Good way to access Spring singleton from within domain objects? to access Spring context.
In your context define a CurrentUserHolder bean defined as singleton bean accessed in @Pre/@Post functions using ApplicationContext.getBean().
CurrentUserHolder bean contains the current user name and its value is mantained from application (can be setted after startup or after user changing).
It's a common solution in Spring-batch to pass data across steps.

Hope can help.

Community
  • 1
  • 1
Luca Basso Ricci
  • 17,829
  • 2
  • 47
  • 69