AuditableEntityListener.java

  1. /*
  2.  * Copyright 2005-2025 the original author or authors.
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package org.openwms.common.jpa;

  17. import org.ameba.http.ctx.CallContext;
  18. import org.ameba.http.ctx.CallContextHolder;
  19. import org.ameba.http.identity.IdentityContextHolder;
  20. import org.hibernate.envers.RevisionListener;
  21. import org.springframework.security.core.context.SecurityContextHolder;

  22. /**
  23.  * An AuditableEntityListener is a Hibernate Envers extension that resolves the current User from Spring Security Context and passes it as
  24.  * user information down to the {@link AuditableRevisionEntity}, that is mapped to the Envers Revision table.
  25.  *
  26.  * @author Heiko Scherrer
  27.  */
  28. public class AuditableEntityListener implements RevisionListener {

  29.     @Override
  30.     public void newRevision(Object revisionEntity) {
  31.         var rev = (AuditableRevisionEntity) revisionEntity;
  32.         if (IdentityContextHolder.getCurrentIdentity() != null) {
  33.             rev.setUserName(IdentityContextHolder.getCurrentIdentity());
  34.         } else if (SecurityContextHolder.getContext().getAuthentication() != null) {
  35.             rev.setUserName(SecurityContextHolder.getContext().getAuthentication().getName());
  36.         } else {
  37.             rev.setUserName("N/A");
  38.         }
  39.         CallContextHolder.getOptionalCallContext().flatMap(CallContext::getOptionalTraceId).ifPresent(rev::setTraceId);
  40.     }
  41. }