ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Data JPA - 엔티티의 생성, 변경한 사람과 시간을 추적(Auditing)
    Spring/Spring Data JPA 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
    반응형

    댓글

Designed by Tistory.