JPA/Spring Data JPA

[JPA] JpaAuditing 기능으로 Entity 등록, 수정 시간 관리하기

KAispread 2022. 12. 16. 23:29
728x90
반응형

프로젝트에서 중요한 도메인에는 상대적으로 많은 데이터가 필요하다. 이러한 데이터들 중 등록일, 수정일과 같은 날짜에 관련된 값은 많은 도메인에서 공통적으로 필요한 컬럼이다. 다음의 예제를 보자.

 

위 3개의 테이블에서는 CREATED_DATE (등록일), MODIFIED_DATE (수정일) 컬럼을 공통적으로 가지고 있다. 이렇게 날짜와 관련된 값들은 일일이 관리하기에 매우 귀찮을 수 있다. 등록일 같은 경우엔 그나마 데이터를 저장하기 전에 한 번만 값을 넣어주면 되지만, 수정일은 데이터를 변경할 때마다 모든 set 이나 update 메서드에 수정 시간을 변경하는 코드를 작성해야한다.

JPA에서는 이러한 문제점을 해결하기 위해 Auditing 이라는 기능을 지원한다. Auditing 의 사전적 정의는 '감사하다', '감시하다'라는 뜻으로, JPA에서는 시간과 관련된 값을 감시하고 값을 넣어주는 기능을 담당하고 있다.

 

@MappedSuperclass

@MappedSuperclass 어노테이션은 상속 매핑을 위한 어노테이션이다.

@MappedSuperclass가 붙은 클래스를 Entity상속하면 해당 컬럼 값들을 상속받아, 데이터베이스 매핑 컬럼에 추가한다.

// 상위 클래스
@Getter
@MappedSuperclass
public abstract class BaseTimeEntity {
    private LocalDateTime createdDate;
    private LocalDateTime modifiedDate;
}


// 상속
@Entity
@Table(name = "USERS")
public class User extends BaseTimeEntity {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "USER_ID")
    private Long id;
    
    // ...
    
    // + BaseTimeEntity의 필드를 상속
}
  • 다음과 같은 코드에서 BaseTimeEntity데이터베이스 테이블에 반영되지 않고, 단순히 createdDate, modifiedDate 컬럼만을 Entity에 물려준다.
  • 즉, 객체가 ORM에 의해 데이터베이스와 매핑될 때 USERS 테이블에는 CREATED_DATE (createdDate), MODIFIED_DATE (modifiedDate) 가 매핑되는 것이다.

USERS 테이블에 BaseTimeEntity 컬럼이 반영됨

 

  • 주의해야 할 점은 @MappedSuperclass는 Entity와 다르게 테이블과 매핑하는 어노테이션이 아니기 때문에 DB 테이블에 반영되지 않는다. 따라서, 일반적으로 단독으로 사용할 일이 없으므로 위와 같이 추상 클래스(abstract)로 선언하는 것이 좋다.

 

 

JPA Auditing 적용

1. @CreatedDate   &   @LastModifiedDate 

@CreatedDate & @LastModifiedDate 어노테이션은 Spring Data 의 어노테이션이다.

  • @CreatedDate가 붙은 필드는 Entity가 생성되어 저장될 때의 시간을 컬럼에 자동으로 넣어준다.
  • @LastModifiedDate 가 붙은 필드는 Entity가 조회되고 값이 변경될 때의 시간을 자동으로 업데이트한다.
    (처음 DB 저장시, 등록일과 동일한 날짜가 삽입된다.)

2.  @EntityListeners (AuditingEntityListener.class)

클래스에 @EntityListners 어노테이션에 이벤트 리스너를 지정할 수 있다.  AuditingEntityListener.class 를 지정하면 해당 클래스에 JPA Auditing 기능이 포함된다. 

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

    @CreatedDate
    public LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime modifiedDate;
}

 

3. @EnableJpaAuditing

Auditing 기능을 활성화시키기 위해선 다음과 같이 Application 클래스에 @EnableJpaAuditing 어노테이션을 추가해주어야한다
(@Configuration 이 붙은 스프링 부트 설정 클래스에 @EnableJpaAuditing 어노테이션을 추가해도 됩니다.)

@EnableJpaAuditing
@SpringBootApplication
public class ModuFormApplication {
	public static void main(String[] args) {
		SpringApplication.run(ModuFormApplication.class, args);
	}
}

 

 

결과

@Test
void auditingTest() {
    User user = User.builder()
            .gender(Gender.MAN)
            .email("adfsd@naver.com")
            .phone("01012345671")
            .birth(19980112L)
            .role(Role.USER)
            .name("기우")
            .nickName("Kai")
            .build();

    User saveUser = userRepository.save(user);
    System.out.println("createdDate = " + saveUser.getCreatedDate());
    System.out.println("modifiedDate = " + saveUser.getModifiedDate());
}

JPA의 테이블 자동 생성 기능 spring.jpa.hibernate.ddl-auto=create 을 설정 후, 간단하게 값을 찍어본 결과 다음과 같이 created_date와 modified_date 컬럼이 삽입되고 값도 자동으로 저장되는 모습을 확인 할 수 있다.

 

 

 

참고

  • 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - 이동욱 저
  • 자바 ORM 표준 JPA 프로그래밍 - 김영한 저
728x90
반응형