스프링 데이터 JPA - Auditing
- 엔티티를 생성, 변경할 때 변경한 사람과 시간을 추적하고 싶다면?
- 등록일
- 수정일
- 등록자
- 수정자
순수 JPA 사용
우선 등록일, 수정일 적용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@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();
}
}
@MappedSuperclass를 반드시 붙혀 줘야 한다. 그 후 엔티티에 가서 extends JpaBaseEntity 하면 된다.
JPA 주요 이벤트 어노테이션
- @PrePersist, @PostPersist
- @PreUpdate, @PostUpdate
스프링 데이터 JPA 사용
설정
@EnableJpaAuditing → 스프링 부트 설정 클래스에 적용해야 함
@EntityListeners(AuditingEntityListener.class) → 엔티티에 적용.
1
2
3
4
5
6
7
8
9
@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
}
1
2
3
4
5
6
7
8
9
10
11
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
여기서 등록자 수정자를 추가하고 싶다면?
- 그런데 모든 테이블 입장에서 이 공통 엔티티가 전부 필요한 데이터는 아닐 수도 있다.
- 시간은 웬만하면 필요 하고, 등록자 수정자는 필요 없을 수도 있다.
- 그럼 등록자 수정자 엔티티를 만들고, 시간 엔티티를 상속 받으면 될 거 같다.
1
2
3
4
5
6
7
8
9
10
11
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseByEntity extends BaseEntity{
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
이렇게 만들었다. 이제 등록자, 수정자가 필요한 엔티티들은 BaseByEntity를 받으면 되고, 필요 없는 곳은 BaseEntity를 상속 받으면 될 것이다.
그런데 createdBy, lastModifiedBy를 무슨 수로 값을 할당 해 줄 것인가?
스프링에 Bean을 등록해 줘야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@EnableJpaAuditing
@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());
}
}
메인 클래스에 AuditorAware를 리턴 하는 auditorProvider 메서드를 만들고 @Bean에 등록해줬다.
값은 그냥 랜덤 아이디 뱉도록 해 놨는데, 실제 사용할 땐 session에서 아이디를 가져 오는 등
동작이 들어가게 될 것이다.
이제 세팅이 끝났고

다음과 같이 상속 받았으면 테스트를 진행 해보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@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.createdDate = " + findMember.getCreatedDate());
System.out.println("findMember.updatedDate = " + findMember.getLastModifiedDate());
System.out.println("findMember.createdBy = " + findMember.getCreatedBy());
System.out.println("findMember.updatedBy = " + findMember.getLastModifiedBy());
}
다음과 같이 찍어 봤고, 결과는
다음과 같이 잘 나왔다.

DB에서도 같은 값을 확인 할 수 있다.
댓글남기기