Everyday Dev System

Auditing 활용하기 본문

내배캠 주요 학습/JPA 심화

Auditing 활용하기

chaeyoung- 2023. 8. 1. 18:21

 

먼저, 선행되어야 하는 것들 입니다.

1. application@EnableJpaAuditing 추가
2. TimeStamp 클래스 생성 후 엔티티 클래스에서 상속 (Channel, Thread, Mention)

 

 

 

아래와 같이 TimeStamp 를 상속한 Channel 클래스의 createdAt, modifiedAt은 Auditing 을 통해 자동으로 들어가는 것을 알 수 있습니다.

 

createdAt, modifiedAt 은 구현체 없이 동작하지만 createdBy, modifiedBy 는 구현체가 필요합니다.

@Entity
public class Channel extends TimeStamp {

}
package me.chaeyoung.jpa.common;

import jakarta.persistence.EntityListeners;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MappedSuperclass;
import java.time.LocalDateTime;
import lombok.Getter;
import me.chaeyoung.jpa.user.User;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

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

  @CreatedDate
  private LocalDateTime createdAt;

  @CreatedBy
  @ManyToOne
  private User createdBy;

  @LastModifiedDate
  private LocalDateTime modifiedAt;

  @LastModifiedBy
  @ManyToOne
  private User modifiedBy;
}

 

 

 

 

다른 방법으로도 할 수 있습니다.

 

1. TimeStamp 클래스 코드 수정

2. TimeStamp를 상속 받은 엔티티 클래스 내에 해당 코드 추가

package me.chaeyoung.jpa.common;

import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import java.time.LocalDateTime;
import lombok.Getter;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

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

  private LocalDateTime createdAt;

  private LocalDateTime modifiedAt;

  public void updateCreatedAt() {
    this.createdAt = LocalDateTime.now();
  }

  public void updateModifiedAt() {
    this.modifiedAt = LocalDateTime.now();
  }
}
  /**
   * 라이프 사이클 메소드 - 외부에서 엔티티를 수정할 메소드를 정의합니다. (단일 책임을 가지도록 주의합니다.)
   */
  @PrePersist
  public void prePersist() {
    super.updateCreatedAt();
    super.updateModifiedAt();
  }

  @PreUpdate
  public void preUpdate() {
    super.updateModifiedAt();
  }

 

 

 

테스트 코드

package me.chaeyoung.jpa.channel;

import com.querydsl.core.types.Predicate;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;

@SpringBootTest
@Transactional
@Rollback(value = false)
class ChannelRepositoryTest {

  @Autowired
  private ChannelRepository channelRepository;


  @Test
  void insertSelectGroupTest() {

    // given
    var newChannel = Channel.builder().name("new-group").build();
    // type 은 null 로 들어갈 것임.

    // when
    var savedChannel = channelRepository.save(newChannel);

    // then
    var foundChannel = channelRepository.findById(savedChannel.getId());
    // DB 에 select 쿼리문을 날리지 않고 영속성 컨텍스트 내에서 가져옴.
    assert foundChannel.get().getId().equals(savedChannel.getId());
  }

  @Test
  void queryDslTest() {
    // given
    var newChannel = Channel.builder().name("chaeyoung").build();
    channelRepository.save(newChannel);

    Predicate predicate = QChannel.channel
        .name.equalsIgnoreCase("CHAEYOUNG");

    // when
    Optional<Channel> optional = channelRepository.findOne(predicate);

    // then
    assert optional.get().getName().equals(newChannel.getName());
  }

}

 

 

 

 

'내배캠 주요 학습 > JPA 심화' 카테고리의 다른 글

QueryDSL의 JPAQueryFactory를 활용한 조회문  (0) 2023.08.02
JPA 활용 장점  (0) 2023.08.01
QueryDSL 활용 코드  (0) 2023.08.01
QueryDsl 기초  (0) 2023.08.01
Repository 에 기능 추가하기  (0) 2023.07.31