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() {
source share