JPA/SpringDataJPA
[SpringDataJPA] Auditing
걸어가는 신사
2022. 6. 4. 16:50
- 엔티티를 생성, 변경할 때 변경한 사람과 시간을 추적하고 싶으면?
- 등록일
- 수정일
- 등록자
- 수정자
순수 JPA 사용
등록일, 수정일 적용
@MappedSuperclass
@Getter
public class JpaBaseEntity {
@Column(updatable = false)
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
@PrePersist
public void prePersist() {
LocalDateTime now = LocalDateTime.now();
createdDate = now;
updatedDate = now;
}
@PreUpdate
public void preUpdate() {
updatedDate = LocalDateTime.now();
}
}
- @PrePersist
- 해당 엔티티를 저장하기 이전 이벤트가 호출된다.
- @PreUpdate
- 해당 엔티티를 업데이트한 이전 이벤트가 호출된다.
스프링 데이터 JPA 사용
1. 설정
(1) @EnableJpaAuditing ⇒ 스프링 부트 설정 클래스에 적용해야 한다.
@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
}
- Spring Boot main 메서드가 선언된 Class 또는 Configuration 클래스에 @EnableJpaAudting 어노테이션을 선언해야 한다.
(2) @EntityListeners(AuditingEntityListener.class) ⇒ 엔티티에 적용
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
...
}
- 엔티티 Class에 @EntityListeners(AuditingEntityListener.class) 어노테이션을 선언해야 한다.
2. 사용 어노테이션
- @CreatedDate : 등록일
- @LastModifiedDate : 수정일
- @CreatedBy : 등록자
- @LastModifiedBy : 수정자
3. 스프링 데이터 Auditing 적용 - 등록일, 수정일, 등록자, 수정자
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
public class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
4. 등록자, 수정자를 처리해주는 AuditorAware 스프링 빈 등록
@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
@Bean
public AuditorAware<String> auditorProvider() {
// SpringSecurityContext 에서 session 정보를 확인한다.
return () -> Optional.of(UUID.randomUUID().toString());
}
}
- 실무에서는 세션 정보나, 스프링 시큐리티 로그인 정보에서 ID를 받는다.
등록일, 수정일, 등록자, 수정자 분리
1. 분리의 필요성
- 실무에서 대부분의 엔티티는 등록시간, 수정시간이 필요하지만, 등록자, 수정자는 없을 수도 있다.
- Base 타입을 분리하고, 원하는 타입을 선택해서 상속한다.
2. 적용
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseTimeEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity extends BaseTimeEntity{
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
- 등록일, 수정일을 필드로 가지는 BaseTimeEntity
- BaseTimeEntity를 상속받고 등록자, 수정자 필드를 가지는 BaseEntity로 분리해주었다.
참고 : 저장시점에 등록자, 등록일 수정일, 수정자 모두 같은 데이터가 저장된다.
데이터가 중복 저장되는 것 같지만, 이렇게 해두면 변경 컬럼만 확인해도 마지막에 업데이트한 유저를 확인할 수 있으므로 유지보수 관점에서 편리하다. 이렇게 하지 않으면 변경 컬럼이 null 일 때 등록 컬럼을 또 찾아야 한다.
참고로 저장시점에 저장 데이터만 입력하고 싶으면 @EnableJpaAuditing(modifyOnCreate = false) 옵션을 사용하면 된다.
반응형