ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Kotlin Jpa Auditing - Entity 수정, 생성기간 저장
    프로젝트/선착순 쿠폰 발급 시스템 2023. 5. 24. 00:01
    728x90

    BaseEntity 정의

    @MappedSuperclass
    @EntityListeners(AuditingEntityListener::class)
    abstract class BaseEntity {
      @CreatedDate
      @Column(nullable = false, updatable = false)
      var createdAt: LocalDateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault())
    
      @LastModifiedDate
      @Column(nullable = false)
      var modifiedAt: LocalDateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault())
    }

    이때 주의할 점은 var으로 정의해주어야 합니다!

    createdAt의 경우에는 처음에 정의되고 변경되지 않기 때문에 val으로 사용하고자 했지만 추후 JPA가 변경하기 때문에 var아 아니라면 런타임 에러가 발생했습니다.

     

    @MappedSuperclass

    공통 매핑 정보가 필요할 때 사용합니다.

    상속받는 클래스에서 createdAt, modifiedAt도 컬럼으로 인식합니다.

    해당 Annotation이 선언된 클래스는 Entity가 아니며, 직접 사용될 일이 없기 때문에 추상 클래스로 선언합니다.

     

    @EntityListeners(AuditingEntityListener::class)

    Entity에서 이벤트가 발생할 때마다 특정 기능을 수행합니다.

    여기서 특정 기능은 Auditing입니다.

     

    @CreatedDate

    생성 시간 자동 저장

     

    @LastModifiedDate

    수정 시간 자동 저장

     

     

    User Entity가 BaseEntity를 상속

    @Entity
    class User(
      @Column(length = 30, nullable = false)
      private val name: String,
    
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      val id: Long
    ): BaseEntity() {
    }

     

     

    Application

    @EnableJpaAuditing
    @SpringBootApplication
    class UserApplication
    
    fun main(args: Array<String>) {
      runApplication<UserApplication>(*args)
    }

    @EnableJpaAuditing

    JPA Auditing 기능을 활성화

    Main Method가 있는 Class에 적용

     

    테스트 코드로 검증해보기

    @Test
    fun `BaseEntity를 통해 저장, 수정일 등록되어야 한다`() {
      //given
      val userId = "myUserId"
      val userInfo = User.testFixture(
        userId = userId
      )
    
      //when
      userPersistenceAdapter.signUp(userInfo)
    
      //then
      val unModifiedUser = userJpaRepository
        .findById(userId)
        .orElseThrow()
    
      assertNotNull(unModifiedUser.createdAt)
      assertNotNull(unModifiedUser.modifiedAt)
      assertEquals(unModifiedUser.createdAt, unModifiedUser.modifiedAt)
    
      unModifiedUser.withdrawUser()
      userJpaRepository.saveAndFlush(unModifiedUser)
      //then
      val modifiedUser = userJpaRepository
        .findById(userId)
        .orElseThrow()
    
      assertNotNull(modifiedUser.createdAt)
      assertNotNull(modifiedUser.modifiedAt)
      assertNotEquals(modifiedUser.createdAt, modifiedUser.modifiedAt)
    }

    초기에 저장될 때는 createdAt과 modifiedAt이 동일합니다.

    하지만 수정이 발생하게 되면 createdAt와 modifiedAt이 달라지게 됩니다.

     

     

    참고자료

    https://dico.me/back-end/articles/308/ko

     

    댓글

Designed by Tistory.