Activating the data JPA Bytecode Enhancement seems to interfere with Spring JPA Auditing mecanism

106 Views Asked by At

I have a Spring Data JPA project where the Bytecode Enhancement has been activated in the pom.xml


      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>11</source>
          <target>11</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.hibernate.orm.tooling</groupId>
        <artifactId>hibernate-enhance-maven-plugin</artifactId>
        <version>5.6.14.Final</version>
        <executions>
          <execution>
            <configuration>
              <failOnError>true</failOnError>
              <enableLazyInitialization>true</enableLazyInitialization>
              <enableDirtyTracking>true</enableDirtyTracking>
            </configuration>
            <goals>
              <goal>**enhance**</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>

On top of that, I have also setup the Spring Audit mecanism. In order to do that, I have an abstract objet called Auditable:

@Getter
@Setter
@MappedSuperclass
@EntityListeners({AuditingEntityListener.class})
public abstract class Auditable {

  @CreatedBy
  @Column(name = "created_by", length = 255, updatable = false)
  protected String createdBy;

  @CreatedDate
  @Column(
      name = "created_date",
      columnDefinition = "timestamp default '2021-06-10 20:47:05.967394'",
      updatable = false)
  @Temporal(TemporalType.TIMESTAMP)
  protected Date createdDate;

  @LastModifiedBy
  @Column(name = "modified_by", length = 255)
  protected String modifiedBy;

  @LastModifiedDate
  @Temporal(TemporalType.TIMESTAMP)
  @Column(
      name = "modified_date",
      columnDefinition = "timestamp default '2021-06-10 20:47:05.967394'")
  protected Date modifiedDate;
 
}

I have also a class that extends the Auditable object:

@Entity
@Table(name = "dashboard")
@NamedQuery(name = "Dashboard.findAll", query = "SELECT d FROM Dashboard d")
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Data
public class Dashboard extends Auditable implements Serializable {
 
  ...
}

Now, in order to activate the Audit mecanism in my project, I have a class AuditorAwareImpl

public class AuditorAwareImpl implements AuditorAware<String> {

  @Override
  public Optional<String> getCurrentAuditor() {
    var auth = SecurityContextHolder.getContext().getAuthentication();
    var retVal = Optional.of("");
    if (auth instanceof AnonymousAuthenticationToken) {
      retVal = retVal.of("anonymous");
    } else if (auth instanceof OAuth2AuthenticationToken) {
      retVal = retVal.of(((DefaultOidcUser) auth.getPrincipal()).getPreferredUsername());
    } else {
      retVal = retVal.of(((HydrowebUserDetails) auth.getPrincipal()).getName());
    }
    return retVal;
  }
}

And a bean of that class loaded in a @Configuration class:

  @Bean
  AuditorAware<String> auditorProvider() {
    return new AuditorAwareImpl();
  }

Now the problem is that I can see the created_by and created_date fields updated in the database when I create a new data into the Dashboard table. On the other hand there is no way to make both fields modified_date and modified_by to be updated when I modify a dashboard entity (nothig is updated/reflected into the Dashboard table).

The exciting point is that if I get rid off the Bytecode Enhancement, then I can make it works properly. All fields are updated as it should be (when creating an entity create fields are updated and when I editing an entity, update fields are also updated properly)...

So it seems that the Bytecode Enhancement interfere in some way with the Audit mecanism, but only for the modifying (_by and _date) columns. With or without bytecode enhancement, the create fields (_by and _date) are alwayds updated.


Is there a way to properly configure and make both concepts work together (bytecode enhancement and spring JPA Auditing)?
Have you already enconter this problem and if it the case, did you find an elegant way to make it works properly. Or it is simply a bug?


From that point, I have found a workaround that works well when both concept are installed (bytecode enhancement and Auditing). We added the following method within the Auditable class:


  @PreUpdate
  void preUpdate(){
    var tempModifiedBy = this.modifiedBy;
    this.setModifiedBy(null);
    this.setModifiedBy(tempModifiedBy);
  }

Doing this seems to "stimulate" the auditing mecanism (when updating an JPA entity). And then both fields are updated with success within the audited table (modified_by and modified_date).

0

There are 0 best solutions below