Issue
So I have an audit class that is using @MappedSuperClass, it updates the values createdBy and updatedBy but it does not add a foreign key on the User entity, so there's no database validation
Here's the Audit Class
@Getter
@Setter
@MappedSuperclass
@JsonIgnoreProperties(
value = {"createdBy", "updatedBy"},
allowGetters = true
)
public abstract class UserDateAudit extends DateAudit {
@CreatedBy
@Column(name = "created_by", nullable = false, updatable = false)
public Long createdBy;
@LastModifiedBy
@Column(name = "updated_by", nullable = false)
public Long updatedBy;
}
I searched on how to do this using @Inheritance but did not completely get it. so How do I achieve the connection between this class and User entity?
Edit 1 Here's the auditing configuration I implement.
@Configuration
@EnableJpaAuditing
public class AuditingConfig {
@Bean
public AuditorAware<Long> auditorProvider() {
return new SpringSecurityAuditAwareImpl();
}
}
class SpringSecurityAuditAwareImpl implements AuditorAware<Long> {
@Override
public Optional<Long> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null ||
!authentication.isAuthenticated() ||
authentication instanceof AnonymousAuthenticationToken) {
return Optional.empty();
}
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
return Optional.ofNullable(userPrincipal.getId());
}
}
Edit 2 to set clear what exactly I mean so how to use something other than @MappedSuperclass to be able achieve this "I want to be able to map the user reference in all tables that inherit the UserDateAudit so that it is a foreign key for all these table (which would add a validation that the user id actually exist) not just a regular column".
Solution
You need to implement the org.springframework.data.domain.AuditorAware
interface and add the logic to retrieve currently logged in user in the getCurrentAuditor
method.
@Component
@RequiredArgsConstructor
public class AuditorResolver implements AuditorAware<YOUR_TYPE> {
@Override
public Optional<YOUR_TYPE> getCurrentAuditor() {
//code to retrieve the currently logged in user and return the id/user object
}
}
See this for an example: https://github.com/gtiwari333/spring-boot-blog-app/blob/master/src/main/java/gt/app/config/AuditorResolver.java
The documentation also describes it beautifully: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#auditing.basics
Answered By - gtiwari333