기록하며 성장한다 - 개발, 회고

개발 회고록

[ 개발 회고록 ] JPA를 활용한, 생성 및 수정 날짜 자동 처리를 위한 공통 Entity 개발.

전대홍 2024. 1. 2. 21:01

 

CreateDateTime 이랑 UpdateDateTime 을 자동으로 관리 할 수는 없을까?
너무 반복되는 로직이 많은거 아니야?

 

 


서론

현재 배달과 관련 된 토이프로젝트를 진행하고 있다.

토이 프로젝트 링크 <<<

중점은 여러가지가 있지만, 배달이나 주문 등에서 마주할 수 있는 여러가지 경우를 알맞은 로직으로 처리하는게 목표이다. ( 예를들면 동시성 이슈라거나 )

현재는 큰 틀을 개발하고 있는데, Entity 를 만들다보니 문득 이런 생각이 들었다.

1. CreateDateTime 과 UpdateTime 은 모든 Entity에 공통으로 들어가는데 공통 Entity 로 뺄 수 있는 방법은 없을까?

2. UpdateDateTime 의 경우, 수정하는 로직마다 this.updateDateTime = updateDateTime 으로 수정해주는데, 자동으로 관리해주는 방법은 없을까?

그렇게 방법을 찾다가, @MappedSuperclass 와, @EntityListeners 를 활용하여 @CreatedDate, @LastModifiedDate 라는 JPA의 어노테이션을 발견할 수 있었다.

 

 


본론

기존에 필자가 작성하였던 Entity 는 아래와 같다.

회원을 관리하는 Member Entity 인데, 아래를 보면 createDateTimeupdateDateTime 이 있다.

그리고 Dto 에서 Entity 로 처음 변환 할 때는, 꼭 createDateTime 을 직접 넣어줬으며, 수정 로직마다 updateDateTime 을 수정하는 로직을 넣어주었다. ( LocalDateTime.now( ); 를 활용하였다. )

예시로 보여준 것은 Member Entity 뿐인데, 다른 Menu 라거나 Store 등의 Entity 도 모두 동일하게 작성하였다.

 

 

하지만 공부를 한 후, 코드를 다음과 같이 수정할 수 있었다.

1. @MappedSuperclass 를 이용한 공통 Entity 분리

이렇게 공통 Entity 를 만들어서 뺄 수 있었다.

@MappedSuperclass 라는 어노테이션을 활용하면 상속 관계를 매핑할 수 있다. 해당 어노테이션으로 공통된 매핑 정보를 가진 부모 클래스를 정의할 수 있었다.

자식 Entity 에서는 extends 로 상속받기만 하므로 편안하다.

 

 

2. @EnableJpaAuditing 과, @EntityListenrs

이 코드와 함께, 맨 위에 게시한 이미지를 보면,

@EnableJpaAuditing 과 @EntityListenrs 가 보일 것이다.

@EnableJpaAuditing 어노테이션은 생성일, 수정일을 자동으로 관리하기 위한 Auditing 을 활성화 시켜준다. Entity 위에 적용시켜도 된다고는 하지만, 기본적으로는 메인 Application 위에 추가 시켜주는 것이 좋다.

@EntityListenrs 는 변화를 감지하는 역할을 한다. 그래서 해당 클래스에 속한 @CreatedDate 와 @LastModifiedDate 어노테이션이 붙은 필드를 생성하거나 수정해주는 작업을 해준다.

그 다음에는 컬럼명 위에 직접적으로 붙는

@CreatedDate 와 @LastModifiedDate 인데 CreateDate 는 말 그대로, 생성 날짜를 자동으로 주입해주며, LastModifiedDate 는 해당 컬럼에 변화가 있을 때마다 날짜를 넣어준다.

그 외에도,

@CreateBy 와 @LastModifiedBy 라는 생성자 수정자도 자동으로 감지하여 주입할 수 있는데, 필자의 프로젝트에는 없으므로 그냥 이런 어노테이션이 있다는 것만 알아두면 좋다. 참고로 이들은 외부에서 주입 받아서 AuditingEntityListener 가 주입할 수 있도록 추가적인 로직을 개발 해주어야 한다.

 

 

 

3. 테스트

잘 동작하는지 Test 는 필수이다.

필자는 DB가 직접 바뀌는 모습을 확인하고 싶었으므로, @Rollback 을 false 로 바꾼 후 테스트를 진행하였다.

 

 

결과는 성공적이었다.

수정한 날짜가 잘 반영되는 모습이다. ^^

 

 


[ 참고 ]

필자도 공부하면서 발견한 것이데,  @Temporal 을 사용하는 방법도 있다고 한다.

그러나 이 방법은 선호하지 않는다고 한다.

DB의 TIMESTAMP 타입과 연동하여 자동으로 관리를 해주는데, Java 의 Date 나 Calendar 하고만 상호작용이 가능하다고 한다.

Java 8 버전 이후로는 LocalDateTime 을 사용하기 때문에 자연스럽게 @Temporal 은 사용하지 않게 되었다고 한다.

덧붙여 설명하자면, Date 나 Calendar 는 가변 객체이며, Thread-Safe 하지 않으므로 사용하지 않는 추세이다.