스프링-BaseEntity 자동으로 채워주기

이진우·2023년 9월 26일
0

스프링 학습

목록 보기
16/41

BaseEntity

우리가 필요한 Entity

@MappedSuperclass
public abstract class BaseEntity {
    private LocalDateTime createdDate;
    private LocalDateTime lastModifiedDate;
}

생성 날짜와 수정날짜가 항상 필요하다고 하자!

그렇다면 이 BaseEntity를 상속한 클래스는 항상 저장할 때마다 createdDate를 사용자가 직접 입력해야 하고, 수정할 떄마다 lastModifiedDate를 입력해야 할까?

그것은 아니다.
그 문제를 해결할 수 있는 방법 2가지가 있다.

JPA만을 사용해서 해결하는 방법

@MappedSuperclass
@Getter
public abstract class BaseEntity{
    @Column(updatable = false)
    private LocalDateTime firstCreatedDate;

    private LocalDateTime lastModifiedDate;

    @PrePersist
    public void prePersist(){
        firstCreatedDate=lastModifiedDate=LocalDateTime.now();
    }
    @PreUpdate
    public void preUpdate(){
        lastModifiedDate=LocalDateTime.now();
    }
  
}

BaseEntity를 위와 같이 만들어 준다. 실제 DB 에 들어가는 클래스가 아니므로 실수로 사용할 수 있는 가능성을 방지하고자 abstract를 붙였다.

@PrePersist는 본래 Entity가 생성될 때 DB에 저장되기 전에 실행하는 메서드이지만 이 경우 이 BaseEntity상속받은 클래스가 생성되기 전에 실행이 된다.

main 함수에

 EntityManagerFactory emf=Persistence.createEntityManagerFactory("hello");
        EntityManager em=emf.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();
        try{
          Member member=new Member();
            System.out.println("------1-----");
          em.persist(member);
            System.out.println("------2------");
          em.flush();
          em.clear();
           tx.commit();

        }catch (Exception e){
            tx.rollback();
        }
        finally {
            em.close();
        }

        emf.close();
    }

위와 같은 코드가 있고 BaseEntity에 아래와 같은 출력문을 포함시켰다.

@PrePersist
 public void prePersist(){
     System.out.println("---prePersist-----");
     createdDate=lastModifiedDate=LocalDateTime.now();
 }

이에 대한 쿼리로

------1-----
---prePersist-----
Hibernate: 
  /* insert jpa_basic_dionisos198.Member
      */ insert 
      into
          Member
          (id, createdBy, createdDate, lastModifiedBy, lastModifiedDate, LOCKER_ID, name) 
      values
          (null, ?, ?, ?, ?, ?, ?)
------2------

이런 순서로 나가는 것을 보았을때 BaseEntity를 상속받은 클래스(Member)가 insert 하기 직전에 @PrePersist가 실행된다는 것을 알 수 있다.

@PreUpdate역시 엔티티가 update 하기 전에 항상 실행되는 메서드로
자동으로 createdDatelastModifiedDate를 집어 넣기에 적합한 메서드이다.

참고로 이렇게 특정 상황이 발생할 때 실행되는 메서드를 콜백 메서드라고 한다.

<결과 화면>

스프링 data jpa 도 함께 사용하는 경우

편리하게 jpa를 사용할 수 있게 스프링 데이터 JPA를 사용할 경우 또 다른 방법을 사용할 수 있다.

먼저 아래와 같이 main 메서드 위에 @EnableJpaAuditing이란 어노테이션을 붙인다.

@SpringBootApplication
@EnableJpaAuditing
public class TestingJpaFunctionApplication {

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

}

audit는 회계를 감사하다 , 검사하다 등의 뜻을 가지고 있는데 @EnableJpaAuditing을 붙임으로써 자동적으로 Entity 감사를 활성화 할 수 있다.

@MappedSuperclass
@EntityListeners(value= AuditingEntityListener.class)
@Getter
public abstract class BaseEntity{
    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime firstCreatedDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;
    
}

위와 같이 BaseEntity위에 @EntityListeners(value=AuditingEntityListener.class를 붙여주어서 사용할 수 있다.

BaseEntity를 상속한 클래스에서 이제 자동으로 firstCreatedDatelastModifiedDate가 채워진다.

firstCreatedDate 결과 화면

lastModifiedDate 결과 화면

profile
기록을 통해 실력을 쌓아가자

0개의 댓글