-
Auditing - 엔티티의 생성 변경 기록JPA/스프링 데이터 JPA 2023. 8. 12. 14:57
엔티티를 생성과 변경을 할 때 변경을 한 사람, 시간 기록을 남겨두면 운영 과정에서 훨씬 도움이 될 것이다.
순수 JPA에서의 Auditing
1. JpaBaseEntity라는 날짜 속성을 알려주는 엔티티를 만든다.
@Getter @MappedSuperclass // 진짜 상속은 아니고 선언된 속성들만 사용한다는 것 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. Member 엔티티에서 JpaBaseEntity를 상속 받는다.
public class Member extends JpaBaseEntity { .... }
3. 테스트에서 실행해보면 만든 날짜와 수정 날짜가 나온다.
@Test public void JpaEventBaseEntity() throws Exception { //given Member member = new Member("member1"); memberRepository.save(member); // @PerPersist 발생 Thread.sleep(100); member.setUsername("member2"); em.flush(); // @PreUpdate em.clear(); //when Member findMember = memberRepository.findById(member.getId()).get(); //then System.out.println("findMember.getCreatedDate = " + findMember.getCreatedDate()); System.out.println("findMember.getUpdatedDate = " + findMember.getUpdatedDate()); }
콘솔 결과 창
findMember.getCreatedDate = 2023-08-12T14:36:13.643212
findMember.getUpdatedDate = 2023-08-12T14:36:13.795051장점은 모든 엔티티에 JpaBaseEntity를 상속 시킬 수 있다. Team의 수정시간을 보고 싶을 때에도 팀에 JpaBaseEntity를 상속 시키면 되니까 엔티티별로 따로 만들 필요가 없다.
스프링 데이터 JPA 사용
1. Main 클래스에 무조건 @EnableJpaAuditing 어노테이션 넣어줘야 함
@EnableJpaAuditing // 필수! @SpringBootApplication public class DataJpaApplication { public static void main(String[] args) { SpringApplication.run(DataJpaApplication.class, args); } }
2. BaseEntity 클래스 생성
@EntityListeners(AuditingEntityListener.class) @MappedSuperclass @Getter public class BaseEntity { @CreatedDate @Column(updatable = false) private LocalDateTime createdDate; @LastModifiedDate private LocalDateTime lastModifiedDate; }
생성 날짜는 @CreatedDate, 수정 날싸는 @LastModifiedDate로 한다.
@EntityListeners(AuditingEntityListener.class)는 변경이 있을 때만 동작한다는 어노테이션? 그런 의미이다.
3. Member의 상속 엔티티 교체
public class Member extends BaseEntity { .... }
이후의 작업은 나머지와 동일한데 스프링 데이터 JPA를 사용하니 훨씬 간편해졌다.
- 날짜 뿐만 아니라 변경한 사용자도 알려주기
1. BaseEntity에 엔티티 추가
@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 createBy; @LastModifiedBy private String lastModifiedBy; }
@CreatedBy는 생성한 사람, @LastModifiedBy는 수정한 사람을 칭한다.
2. 메인 클래스에 스프링 빈 주입
@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()); // 원래는 스프링 시큐리티에서 세션을 꺼낸 다음에 그 id를 넣어줘야 한다. } }
auditorProvier()라는 스프링 빈을 주입한다. 원래는 UUID 값이 아니라 스프링 시큐리티나 http에서 세션을 꺼낸 다음 그 사람의 id를 넣어줘야 하는데, 지금은 예제니까 UUID를 사용했다.
3. 테스트
@Test public void JpaEventBaseEntity() throws Exception { //given Member member = new Member("member1"); memberRepository.save(member); // @PerPersist 발생 Thread.sleep(100); member.setUsername("member2"); em.flush(); // @PreUpdate em.clear(); //when Member findMember = memberRepository.findById(member.getId()).get(); //then System.out.println("findMember.getCreatedDate = " + findMember.getCreatedDate()); System.out.println("findMember.getUpdatedDate = " + findMember.getLastModifiedDate()); System.out.println("findMember.getCreatedBy = " + findMember.getCreateBy()); System.out.println("findMember.getUpdatedBy = " + findMember.getLastModifiedBy()); }
테스트를 해보면 시간 이외에 생성, 변경한 사람의 UUID도 출력해준다.
콘솔 결과 창
findMember.getCreatedDate = 2023-08-12T14:49:40.986619
findMember.getUpdatedDate = 2023-08-12T14:49:41.130150
findMember.getCreatedDate = d63da64a-e66c-48da-b173-4a940a7a4672
findMember.getUpdatedDate = 9dd20bcb-dd73-42e2-ae4c-5f5615c961e8'JPA > 스프링 데이터 JPA' 카테고리의 다른 글
Web 확장 - 페이징과 정렬 (0) 2023.08.12 스프링 데이터 JPA에서의 사용자 정의 리포지토리 (0) 2023.08.12 JPA Hint (0) 2023.08.12 @EntityGraph - 어노테이션으로 fetch join (0) 2023.08.12 벌크성 수정 쿼리 (0) 2023.08.11