Auditing
엔티티를 생성, 변경할 때 변경한 사람과 시간을 추적하고 싶으면?
- 등록일
- 수정일
- 등록자
- 수정자
순수 JPA 사용하여 등록일, 수정일 적용해보자.
@MappedSuperclass
@Getter
public class JpaBaseEntity {
@Column(updatable = false)
private LocalDateTime createTime;
private LocalDateTime updateTime;
@PrePersist
public void prePersist() {
this.createTime = LocalDateTime.now();
this.updateTime = LocalDateTime.now();
}
@PreUpdate
public void preUpdate() {
this.updateTime = LocalDateTime.now();
}
}
public class Member extends JpaBaseEntity {}
확인 코드
@Test
public void JpaEventBaseEntity() throws Exception{
// given
Member member = new Member("member1");
memberRepository.save(member); // @PrePersist
Thread.sleep(100);
member.setUsername("member2");
em.flush(); // @PreUpdate
em.clear();
// when
Member findMember = memberRepository.findById(member.getId()).get();
// then
System.out.println("findMember.getCreateTime() = " + findMember.getCreateTime());
System.out.println("findMember.getUpdateTime() = " + findMember.getUpdateTime());
}
JPA 주요 이벤트 어노테이션
- @PrePersist, @PostPersist
- @PreUpdate, @PostUpdate
스프링 데이터 JPA 사용을 사용하여 더욱 깔끔하게 코드를 작성할 수 있다.
사용 어노테이션
- @CreatedDate
- @LastModifiedDate
- @CreatedBy
- @LastModifiedBy
설정
@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
}
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createTime;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
- @EnableJpaAuditing → 스프링 부트 설정 클래스에 적용해야함
- @EntityListeners(AuditingEntityListener.class) → 엔티티에 적용
스프링 데이터 Auditing 적용 - 등록자, 수정자
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createTime;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
@CreatedBy
@Column(updatable = false)
private String createBy;
@LastModifiedBy
private String lastModifiedBy;
}
@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
@Bean
public AuditorAware<String> auditorProvider() {
// 실무에서는 SecurityContext에서 사용자를 꺼내는 등의 작업을 하면 됨.
return () -> Optional.of(UUID.randomUUID().toString());
}
}
- 등록자, 수정자를 처리해주는 `AuditorAware` 스프링 빈 등록
- 실무에서는 세션 정보나, 스프링 시큐리티 로그인 정보에서 ID를 받음
-
주의: DataJpaApplication 에 @EnableJpaAuditing도 함께 등록해야 한다.
참고
public class BaseTimeEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
public class BaseEntity extends BaseTimeEntity {
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
- 실무에서 대부분의 엔티티는 등록시간, 수정시간이 필요하지만, 등록자, 수정자는 없을 수도 있다.
- 그래서 다음과 같이 Base 타입을 분리하고, 원하는 타입을 선택해서 상속한다.
저장 시점에 저장 데이터만 저장
@EnableJpaAuditing(modifyOnCreate = false)
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
@Bean
public AuditorAware<String> auditorProvider() {
return () -> Optional.of(UUID.randomUUID().toString());
}
}
저장시점에 등록일, 등록자는 물론이고, 수정일, 수정자도 같은 데이터가 저장된다.
데이터가 중복 저장되는 것 같지만, 이렇게 해두면 변경 컬럼만 확인해도 마지막에 업데이트한 유저를 확인 할 수 있으므로 유지보수 관점 에서 편리하다. 이렇게 하지 않으면 변경 컬럼이 `null` 일때 등록 컬럼을 또 찾아야 한다. 그럼에도 불구하고 저장 시점에 저장 데이터만 저장하고 싶다면 위를 참고하면 된다. - @EnableJpaAuditing(modifyOnCreate = false) 옵션을 사용
전체 적용 방법 - (META-INF/orm.xml)
// META-INF/orm.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
http://xmlns.jcp.org/xml/ns/persistence/orm_2_2.xsd"
version="2.2">
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener
class="org.springframework.data.jpa.domain.support.AuditingEntityListener"/>
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
- @EntityListeners(AuditingEntityListener.class) 를 생략하고 스프링 데이터 JPA 가 제공하는 이벤트를 엔티티 전체에 적용하려면 orm.xml에 다음과 같이 등록하면 된다.
'JPA' 카테고리의 다른 글
[Spring Data JPA] 구현체 분석 (0) | 2025.01.18 |
---|---|
[Spring Data JPA] WEB 확장 기능, 페이지 1처리 코드 구현 (0) | 2025.01.18 |
[Spring Data JPA] 사용자 정의 리포지토리 구현 (0) | 2025.01.18 |
[Spring Data JPA] JPA Hint & Lock (0) | 2025.01.18 |
[Spring Data JPA] @EntityGraph (0) | 2025.01.17 |