본문 바로가기
JPA

[JPA] 생성일, 수정일 자동 기입 기능 추가하기 (AuditingEntityListener)

by codeyaki 2023. 7. 9.
반응형

게시글과 같은 기능을 구현하다 보면 생성일, 수정일을 관리해야 하는 경우가 흔하게 발생한다.

이럴 때 서비스로직에 직접 생성, 수정 시에 해당 날짜를 생성일, 수정일 컬럼에 직접 update 하는 방식으로 구현할 수 있다.

하지만 이렇게 되면 사람이 코드를 작성하다 보니 까먹고 추가를 안 하는 경우가 생겨 정상적으로 동작하지 않는 컬럼이 될 수 있다.

이러한 부분을 해결하기 위해서 엔티티에 리스너를 추가하여 엔티티를 조작할 때 추가적인 로직을 설정할 수 있다.

바로 AuditingEntityListener를 이용하는 것이다.

 

EntityListener

EntityListener는 엔티티에 이벤트가 발생하는 것을 감지하여 동작하는 로직을 구현할 수 있도록 해준다.

JPA는 7가지의 이벤트를 감지할 수 있다.

사용 방법은 엔티티에 메서드를 만들고 어노테이션을 달아주는 것이다.

  • 메서드 호출 전
    • @PrePersist : Persist(insert) 메서드가 호출되기 전에 실행되는 메서드
    • @PreUpdate : merge메서드가 호출되기 전에 실행되는 메서드
    • @PreRemove : Delete메서드가 호출되기 전에 실행되는 메서드
  • 메서드 호출 후
    • @PostPersist : Persist(insert) 메서드가 호출된 이후에 실행되는 메서드
    • @PostUpdate : merge메서드가 호출된 후에 실행되는 메서드
    • @PostRemove : Delete메서드가 호출된 후에 실행되는 메서드
    • @PostLoad : Select조회가 일어난 직후에 실행되는 메서드

사용예시는 이러하다.

...
@Entity
public class Post {

    ...

    @PrePersist
    private void preEvent(){
        System.out.println("preEvent!!");
    }
}

해당 이벤트는 Persist가 발생하기 전에 동작하게 된다. 실행 예시를 보면 preEvent!! 가 insert 되기 전에 동작한 것을 확인할 수 있다.

이러한 기능을 이용해서 내가 직접 구현할 수도 있지만 Spring Data에서 사용자들이 많이 사용하는 자동으로 생성일, 수정일을 기입해 주는 리스너를 만들어 두었다.

 

AuditingEntityListener

기본적으로 AuditingEntityListener는 생성일, 마지막 수정일, 작성자, 마지막 수정자를 자동으로 기입해 줄 수 있다.

사용하기 위해서는 먼저 Springboot configuration 클래스에 @EnableJpaAuditing을 넣어주어야 한다.

@SpringBootApplication
@EnableJpaAuditing // 추가
public class AppApplication {

	public static void main(String[] args) {
		SpringApplication.run(AppApplication.class, args);
	}

}

그 뒤 Entity에 @EntityListeners(AuditingEntityListener.class)를 달아주면 기본적인 세팅이 끝나게 된다!

이제 해당 엔티티에서 수정이나 생성 시 달아줄 컬럼에 @CreatedDate, @LastModifiedDate, @CreatedBy, @LastModifiedBy를 달아주면 동작하게 된다!

주의할 점은 CreatedBy와 LastModifiedBy 같은 경우에는 Spring Security에서 지원하는 AuditorAware를 지정해두어야 한다.

현재 Security까지 다루지는 않기 때문에 나중에 다뤄봐야겠다.

...
@Entity
@EntityListeners(AuditingEntityListener.class) // 추가
public class Post {

    ...
    @Column(name = "posted_date", updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @CreatedDate // 추가
    private java.util.Date postedDate;
    
    @Column(name = "modified_date")
    @Temporal(TemporalType.TIMESTAMP)
    @LastModifiedDate // 추가
    private java.util.Date modifiedDate;
    }
}
  • 생성일 같은 경우에는 생성될 때 이후로 수정되는 것을 방지하기 위해서 updatable을 false로 해주는 것이 좋다!
  • java.util.Date, java.sql.Date, LocalDateTime 사용 방법은 동일하다.
반응형