[Spring Boot] 쇼핑몰 프로젝트 (9) - Auditing을 이용한 엔티티 공통 속성 공통화

YulHee Kim·2021년 12월 10일
0

✏️ Auditing을 이용한 엔티티 공통 속성 공통화

실제 서비스를 운영할 때는 보통 등록시간과 수정시간, 등록자, 수정자를 테이블에 넣어놓고 활용합니다. 그리고 데이터가 생성되거나 수정될 때 시간을 기록해주고, 어떤 사용자가 등록했는지 아이디를 남깁니다. 이 컬럼들은 버그가 있거나 문의가 들어왔을 때 활용이 가능합니다.

Spring Data Jpa에서는 Auditing 기능을 제공하여 엔티티가 저장 또는 수정될 때 자동으로 등록일, 수정일, 등록자, 수정자를 입력해줍니다. Audit의 사전적 정의는 '감시하다'입니다. 즉, 엔티티의 생성과 수정을 감시하고 있는 것입니다. 이런 공통 멤버 변수들을 추상 클래스로 만들고, 해당 추상 클래스를 상속받는 형태로 엔티티를 리팩토링 하겠습니다.

현재 로그인한 사용자의 정보를 등록자와 수정자로 지정하기 위해서 Auditor Aware 인터페이스를 구현한 클래스를 생성합니다.

public class AuditorAwareImpl implements AuditorAware<String> {

    @Override
    public Optional<String> getCurrentAuditor() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String userId = "";
        if(authentication != null){
            userId = authentication.getName();
        }
        return Optional.of(userId);
    }

}

현재 로그인 한 사용자의 정보를 조회하여 사용자의 이름을 등록자와 수정자로 지정합니다.

Auditing 기능을 사용하기 위해서 Config 파일을 생성하겠습니다.

@Configuration
@EnableJpaAuditing
public class AuditConfig {

    @Bean
    public AuditorAware<String> auditorProvider() {
        return new AuditorAwareImpl();
    }
}

@EnableJpaAuditing 어노테이션은 JPA의 Auditing 기능을 활성화합니다. 그리고 등록자와 수정자를 처리해주는 AuditorAware을 빈으로 등록합니다.

✏️ BaseTimeEntity 클래스

등록자, 수정자를 넣지 않는 테이블도 있을 수 있기 때문에 BaseTimeEntity를 상속받을 수 있도록 BaseTimeEntity 클래스를 생성해주겠습니다.

@EntityListeners(value = {AuditingEntityListener.class})
@MappedSuperclass
@Getter @Setter
public abstract class BaseTimeEntity {

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

    @LastModifiedDate
    private LocalDateTime updateTime;

}

@MappedSuperclass 어노테이션은 공통 매핑 정보가 필요할 때 사용하는 어노테이션으로 부모 클래스를 상속받는 자식 클래스에 매핑 정보만 제공합니다.

✏️ BaseEntity

BaseEntity는 위에서 만든 BaseTimeEntity를 상속받고 있습니다. 등록일, 수정일, 등록자, 수정자를 모두 갖는 엔티티는 BaseEntity를 상속받으면 됩니다.

@EntityListeners(value = {AuditingEntityListener.class})
@MappedSuperclass
@Getter
public abstract class BaseEntity extends BaseTimeEntity{

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

    @LastModifiedBy
    private String modifiedBy;

}

Member 엔티티에 Auditing 기능을 적용하기 위해 BaseEntity 클래스를 상속받도록 한 뒤, 회원 엔티티 저장 시 자동으로 등록자, 수정자, 등록시간, 수정시간이 저장되는지 테스트 코드를 작성하겠습니다.

✏️ MemberTest

@SpringBootTest
@Transactional
@TestPropertySource(locations="classpath:application-test.properties")
public class MemberTest {

    @Autowired
    MemberRepository memberRepository;

    @PersistenceContext
    EntityManager em;

    @Test
    @DisplayName("Auditing 테스트")
    @WithMockUser(username = "gildong", roles = "USER")
    public void auditingTest(){
        Member newMember = new Member();
        memberRepository.save(newMember);

        em.flush();
        em.clear();

        Member member = memberRepository.findById(newMember.getId())
                .orElseThrow(EntityNotFoundException::new);

        System.out.println("register time : " + member.getRegTime());
        System.out.println("update time : " + member.getUpdateTime());
        System.out.println("create member : " + member.getCreatedBy());
        System.out.println("modify member : " + member.getModifiedBy());
    }

}

나머지 엔티티도 BaseEntity를 상속받도록 수정하겠습니다.

profile
백엔드 개발자

0개의 댓글