Spring/Spring Data JPA
Spring Data JPA - 엔티티의 생성, 변경한 사람과 시간을 추적(Auditing)
jddng
2022. 3. 21. 11:34
728x90
반응형
엔티티의 생성, 변경한 사람과 시간을 추적(Auditing)
- 기본적으로 운영할 때는 등록일, 수정일, 등록자, 수정자를 모든 테이블에 적용하는 것이 좋다.
- 누가 등록했고, 누가 수정했는지 추적하기가 쉽다.
- 유지보수에 용이
순수 JPA 사용의 Auditing
- @MappedSuperclass : 해당 필드들을 사용할 수 있도록 맵핑해주는 어노테이션
- @PrePersist : 저장할 때 이벤트 실행
- @PreUpdate : 수정할 때 이벤트 실행
1. 모든 Entity에 적용하는 공통 Entity 생성
@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();
}
}
2. Entity에 상속받아 사용
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.createdDate = " + findMember.getCreatedDate());
System.out.println("findMember.updatedDate = " + findMember.getUpdatedDate());
}
Spring Data JPA에서의 Auditing
- 설정 - @EnableJpaAuditing : 스프링 부트 설정 클래스에 적용해야 한다.(ex - xxxxapplication.class)
- - @EntityListeners(AuditingEntityListener.class) : 엔티티에 적용해야 한다.
- 사용 어노테이션
- @CreatedDate
- @LastModifiedDate
- @CreateBy
- @LastModifiedBy
1. 모든 Entity에 적용하는 공통 Entity 생성
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
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;
}
2. Entity에 상속받아 사용
public class Member extends BaseEntity {
...
}
3. 등록자, 수정자를 처리해주는 AuditorAware 스프링 빈 등록( xxxxApllication.class)
실무에서는 세션 정보나, 스프링 시큐리티 로그인 정보에서 ID를 받는다.
@Bean
public AuditorAware<String> auditorProvider() {
return () -> Optional.of(UUID.randomUUID().toString());
}
실무에서 대부분의 엔티티는 등록시간, 수정시간이 필요하지만, 등록자, 수정자는 사용하지 않는 경우도 있다. 따라서 다음과 같이 Base 타입을 분리하고, 원하는 타입을 선택해서 상속한다.
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;
}
참고
임베디드 타입과 @MappedSuperclass의 차이는
선택의 차이일뿐
상속을 사용하는 것(@MappedSuperclass)과 위임을 사용하는 것(임베디드)의 차이
JPQL 쿼리를 사용할 때 상속과 위임의 차이는 다음과 같다.
임베디드 : select m from Member m where m.traceDate.createdDate > ?
상속 : select m from Member m where m.createdDate > ?
728x90
반응형