
엔티티에 로그성 데이터를 남길 필요가 있을 경우가 있다. 예를 들어 createdAt, updatedAt과 같은 필드들을 통해 데이터가 언제 생성되고 마지막으로 수정되었는지 등을 말이다.
JPA는 Jpa Auditing 이라는 기능을 통해 해당 로직을 따로 구현할 필요 없이 어노테이션만 붙여 간단하게 구현할 수 있도록 해준다.
Jpa Auditing을 사용하기 위해서 기능을 활성화 해 줄 필요가 있다.
@Configuration
@EnableJpaAuditing
public class JpaConfig {
}
보통 위와 같이 별도의 Configuration 클래스를 통해 Jpa를 설정할 것이다. 그 설정 클래스에 @EnableJpaAuditing를 붙여부면 된다.
@SpringBootApplication
@EnableJpaAuditing
public class TentenBackendApplication {
public static void main(String[] args) {
SpringApplication.run(TentenBackendApplication.class, args);
}
}
아니면 그냥 위와 같이 메인 애플리케이션 클래스에 붙여줘도 된다!
Jpa Auditing을 적용 시킬 엔티티에도 추가 어노테이션이 필요하다.
@Data
@MappedSuperclass
@EntityListeners(value = AuditingEntityListener.class)
public abstract class BaseEntity {
}
해당 엔티티에 위와 같이 @EntityListeners(value = AuditingEntityListener.class)를 붙여주면 된다!
위 필드들에 Jpa Auditing을 적용하는 것은 비교적 간단하다. Spring에서 어노테이션을 제공해주기 때문이다.
@Data
@MappedSuperclass
@EntityListeners(value = AuditingEntityListener.class)
public abstract class BaseEntity {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
@CreatedDate와 @LastModifiedDate를 붙여주면 된다. Jpa Auditing이 활성화 되어 있고 해당 어노테이션이 붙은 필드들이 있다면 자동으로 데이터 생성과 수정 시 필드에 해당 시간을 넣어준다.
생성 시간과 수정 시간 뿐만 아니라 누가 생성했는지와 누가 수정하였는지도 기록할 필요가 있다. 그를 위해 @CreatedBy와 @LastModifiedBy 어노테이션을 제공해준다.
@CreatedDate와 @LastModifiedDate와 달리 @CreatedBy와 @LastModifiedBy를 사용하기 위해서는 별도의 구현이 필요하다. AuditorAwar<T> 인터페이스를 구현하여 Bean으로 등록해야 한다.
@Component
public class AuditorAwareImpl implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return Optional.empty();
}
Object principal = authentication.getPrincipal();
if (principal instanceof UserDetails) {
return Optional.of(((UserDetails) principal).getUsername());
}
return Optional.empty();
}
}
제네릭 타입으로는 @CreatedBy와 @LastModifiedBy를 붙인 필드의 데이터 타입을 지정해주면 된다. 누가 생성이나 수정을 했는지를 식별 할 수 있도록 엔티티의 PK나 unique 필드를 지정해주면 된다.
이후 getCurrentAuditor() 메소드를 오버라이딩 해야 하는데 어노테이션이 붙은 필드에 넣어줄 값을 리턴하면 된다..
나같은 경우 현재 요청을 한 유저의 정보를 넣어주기 위해 SecurityContextHolder에서 Authentication을 가져온 다음 Username을 리턴해주었다.
@Data
@MappedSuperclass
@EntityListeners(value = AuditingEntityListener.class)
public abstract class BaseEntity {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String updatedBy;
}
그 후 Jpa Auditing을 적용 시킬 엔티티의 필드에 @CreatedBy와 @LastModifiedBy를 붙여주면 된다!!