Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

Auditing 본문

인프런/[인프런] Spring Data JPA

Auditing

Seung__ 2021. 8. 30. 23:41

1. Auditing


  • 엔티티를 생성 및 변경할 때 변경한 사람과 시간을 추적하고 싶으면?
    • 등록일
    • 수정일
    • 등록자
    • 수정자

 

 

2. JPA 활용


  • JpaBaseEntity
    • @MappedSuperclass
    • Designates a class whose mapping information is applied to the entities that inherit from it. 
    • A mapped superclass has no separate table defined for it.
    • 해당 annotation은  상속받는 엔티티에  매핑 정보를 전달할 클래스를 지정.
    • 즉, 해당 annotation이 붙은 클래스의 속성 정보만 하위 클래스에 전달하여 하위클래스에서 사용할 수 있음.
    • 해당 annotation이 붙은 클래스는 별도 table을 갖지 않음. 
@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();
    }

}
  • Member
    • JpaBaseEntity를 상속받음
    • 상속을 받음으로서 @MappedSuperclass에 의해 JpaBaseEntity의 속성을 사용할 수 있다.
public class Member extends JpaBaseEntity{
  • Member table에 JpaBaseEntity의 속성이 추가됨.
    create table member (
       member_id bigint not null,
        created_date timestamp,
        updated_date timestamp,
        age integer not null,
        user_name varchar(255),
        team_id bigint,
        primary key (member_id)
    )
  • Test
   @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.getCreatedDate() = " + findMember.getCreatedDate());
        System.out.println("findMember.getUpdatedDate() = " + findMember.getUpdatedDate());
    }
findMember.getCreatedDate() = 2021-08-30T23:15:48.054363
findMember.getUpdatedDate() = 2021-08-30T23:15:48.235787

 

 

3. JPA 주요 이벤트 annotation


  • @PrePersist, @PostPersist
  • @PreUpdate, @PostUpdate

 

 

 

 

4. SpringDataJPA 활용


  • 설정
    • @EnableJpaAuditing 스프링 부트 설정 클래스에 적용해야함
      @SpringBootApplication
      @EnableJpaAuditing
      public class SpringDataJpaApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(SpringDataJpaApplication.class, args);
          }
      
      }​
    • @EntityListeners(AuditingEntityListener.class) 엔티티에 적용
      • @EntityListeners(AuditingEntityListener.class) : 엔티티 리스너로 등록
      • 와 간단
        @EntityListeners(AuditingEntityListener.class)
        @MappedSuperclass
        @Getter
        public class BaseEntity {
            
            @CreatedDate
            @Column(updatable = false)
            private LocalDateTime createdDate;
            
            @LastModifiedDate
            private LocalDateTime lastModifiedDate;
        }​
  • Member Class
    • 기존 JpaBaseEntity를 BaseEntity로 변경
public class Member extends BaseEntity{

 

 

 

5. 등록자 수정자


  • 등록자, 수정자를 처리해주는 AuditorAware 스프링 빈 등록이 필요하다.
  • AuditorAware를 등록해야 @CreatedBy, @LastModifiedBy 실행 시 빈에서 찾아서 값을 채움.
  • 아래 예시는 임의의UUID 생성.
@SpringBootApplication
@EnableJpaAuditing
public class SpringDataJpaApplication {

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

    @Bean
    public AuditorAware<String> auditorProvider(){
        return () -> Optional.of(UUID.randomUUID().toString());
    }

}
  • BaseEntity
    • @CreatedBy, @LastModifiedBy
@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;

}
  • Test
  @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.getCreatedDate() = " + findMember.getCreatedDate());
        System.out.println("findMember.getCreatedBy() = " + findMember.getCreatedBy());
        System.out.println("findMember.getUpdatedDate() = " + findMember.getLastModifiedDate());
        System.out.println("findMember.getLastModifiedBy() = " + findMember.getLastModifiedBy());
    }
  • Result
findMember.getCreatedDate() = 2021-08-30T23:31:41.942533
findMember.getCreatedBy() = 019d4f5d-1044-493c-907f-dab3ed319c78
findMember.getUpdatedDate() = 2021-08-30T23:31:42.100038
findMember.getLastModifiedBy() = ee981afd-42fe-4800-93a5-aec0255ff306

 

6. 참고


  • 실무에서 대부분의 엔티티는 등록시간, 수정시간이 필요하지만,
  • 등록자, 수정자는 없을 수도 있다.
  • 그러면 time과 관련된  Base 타입을 분리해두자.

 

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

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

    @LastModifiedBy
    private String lastModifiedBy;

}

 

 

7. GitHub : 210830 Auditing


 

GitHub - bsh6463/SpringDataJpa

Contribute to bsh6463/SpringDataJpa development by creating an account on GitHub.

github.com

 

'인프런 > [인프런] Spring Data JPA' 카테고리의 다른 글

SpringDataJpa의 구현체  (0) 2021.08.31
Web 확장 : 도메인 클래스 컨버터, 페이징 & 정렬  (0) 2021.08.31
사용자 정의 Repository  (0) 2021.08.30
JPA Hint & Lock  (0) 2021.08.29
@EntityGraph  (0) 2021.08.29
Comments