본문 바로가기
웹/Spring Data

[스프링 데이터 JPA] 6. Auditing

by 두잇베스트 2020. 12. 21.

Auditing

  • 엔티티를 생성, 변경할때 변경한 사람과 시간을 알고 싶으면 스프링 데이터 jpa는 이를 손쉽게 알려준다.
    • 등록일
    • 수정일
    • 등록자
    • 수정자
  • 스프링 부트 설정 클래스
package study.datajpa;

import ...;

@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(DataJpaApplication.class, args);
    }

@SpringBootApplication 이 있는 클래스에 @EnableJpaAuditing 을 적용해줘야한다.

그리고 나서 사용하는 어노테이션은

  • @CreatedDate
  • @LastModifiedDate
  • @CreatedBy
  • @LastModifiedBy

스프링 데이터 Auditing 적용


@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity { 

    @CreatedBy
    @Column(updatable = false)
    private String createdBy; 

    @LastModifiedBy
    private String lastModifiedBy;

      @CreatedDate
      @Column(updatable = false)
      private LocalDateTime createdDate;

      @LastModifiedDate
      private LocalDateTime lastModifiedDate;
}

엔티티에는 @EntityListeners(AuditingEntityListener.class 를 적용해줘야한다. 그리고 이 클래스들을 필요한 엔티티들이 상속 받으면 된다.

 

 

등록자, 수정자를 처리해주는 AuditorAware 스프링 빈으로 등록

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()); 
        // ==
//        return new AuditorAware<String>() {
//            @Override
//            public Optional<String> getCurrentAuditor() {
//                return Optional.of(UUID.randomUUID().toString());
//            }
//        };

    }
}

저는 랜덤으로 등록자와 수정자를 받았지만, 후의 스프링 시큐리티에서는 세션 정보를 꺼내서 사용한다.

 

 

 

테스트 코드

 @Test
    public void Auditing_test() throws Exception {
        //given
        Member member = new Member("member1");
        memberRepository.save(member); 

        Thread.sleep(100);
        member.setUsername("member2");

        em.flush();
        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.lastmodifiedBy= " + findMember.getLastModifiedBy());

    }

다음과 같이 잘 나오게 된다. 등록자, 등록일, 수정자, 수정일이 필요한 엔티티들이 상속받아서 사용한다.

 

 

 

여기서 코드를 좀 더 이쁘게 다듬으면
기존의 BaseEntity 를 분리시켜보자.

 

BaseEntity

package study.datajpa.entity;

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity extends BaseTimeEntity{ 
    @CreatedBy
    @Column(updatable = false)
    private String createdBy; 

    @LastModifiedBy
    private String lastModifiedBy;
}

 

BaseTimeEntity

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseTimeEntity {

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;
}

이렇게 분리시킨 이유는 시간 데이터는 웬만하면 대부분의 엔티티들이 필요하게 된다. 그래서 이것을 최상위로 두고 시간 데이터만 사용하고 싶을때 BaseTimeEntity 를 상속 받아서 사용하면 되고, 거기에 더불어서 등록자, 수정자 함께 필요하게 됐을때 BaseEntity 를 상속 받아서 사용하면 된다.

 

 

Reference

댓글