Spring Audit object changes even if nothing has changed

NOTE. This is a tricky question, so hopefully I reviewed the relevant parts. If not, I will edit and add additional information upon request.

We use Spring (4.1.0) with Hibernate (4.3.6), and we have defined a base class that extends to all of our entities called BaseAuditableEntity (code below). When an object is loaded into the @Transactional method, and then modified and saved, this modified_by_user_id and modified_ts object is updated with the identifier of the user who logged in when any change was made.

Our problem is that whenever the AppUser (which also extends BaseAuditableEntity) is loaded into one of these @Transactional methods, it also sets that modified_by_user_id and modified_ts set, even if they were not modified. This creates a problem because we write our user table with almost every query when we donโ€™t need to. Note that this can also affect @Transactional methods that do not load AppUser explicitly, because AuditorBean loads AppUser itself.

I assume this has something to do with the fact that the AppUser object is part of BaseAuditableEntity itself. Can someone confirm this? Is there any way to solve this problem?

Our BaseAuditableEntity class, which extends every object, including AppUser:

 @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public abstract class BaseAuditableEntity implements Auditable<AppUser, Long> { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hibernate_sequence") @SequenceGenerator(name = "hibernate_sequence", sequenceName = "blah_sequence", allocationSize = 1) @Column(name = "id") private Long id; @CreatedBy @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "created_by_user_id") private AppUser createdBy; @LastModifiedBy @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "modified_by_user_id") private AppUser lastModifiedBy; @Column(name = "created_ts") @CreatedDate @Temporal(TemporalType.TIMESTAMP) private Date createdDate; @Column(name = "modified_ts") @LastModifiedDate @Temporal(TemporalType.TIMESTAMP) private Date lastModifiedDate; // ... } 

Our JpaConfig :

 @Configuration @EnableJpaRepositories(basePackages = { "blah.blah.blah"}) @ComponentScan(basePackageClasses = {AuditorBean.class}) @EnableTransactionManagement @EnableJpaAuditing(auditorAwareRef = "auditorBean") public class JpaConfig extends BaseConfig { // ... } 

And our AuditorBean :

 @Component public class AuditorBean implements AuditorAware<AppUser> { @Override public AppUser getCurrentAuditor() { // omitting some code that finds a user. I think the only relevant thing here // is that we're using the repo to find the user by ID and not using an // entity that already been loaded return userRepository.findOne(id); } } 
+5
source share
1 answer

My suggestion is to keep the audit simple and vague

 @CreatedBy private Long createdBy; 

without actual association and store only the AppUser identifier there.

@Component Public Class AuditorBean implements AuditorAware {

 @Override public Long getCurrentAuditor() { // .... find out the id return id; } 

}

0
source

Source: https://habr.com/ru/post/1209386/


All Articles