본문 바로가기

프로그래밍/JAVA

[JPA] EntityListeners 활용

728x90
반응형

EntityListener 란 Entity가 삽입, 삭제, 수정, 조회 등의 작업을 할 때 전, 후에 어떠한 작업을 하기 위해 이벤트 처리를 위한 어노테이션이다

 

EntityListener의 종류

@PrePersist : Persist(Insert) 메서드가 호출되기 전에 실행되는 메서드
@PreUpdate : Merge(Update) 메서드가 호출되기 전에 실행되는 메서드
@PreRemove : Remove(Delete) 메서드가 호출 되기 전에 실행되는 메서드
@PostPersist : Persist(Insert) 메서드가 호출된 후에 실행되는 메서드
@PostUpdate : Merge(Update) 메서드가 호출 된 후에 실행되는 메서드
@PostRemove : Remove(Delete) 메서드가 호울 된 후에 실행되는 메서드
@PostLoad : Select 조회가 실행된 직후에 실행되는 메서드

간단한 사용 예제 

데이터가 삽입되기 전과 수정되기 전 createdAt, updatedAt의 시간을 조작

 

공통으로 사용할 수 있는 EntityListener 클래스를 생성

 

CustomerEntityListener.java

import javax.persistence.EntityListeners;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import java.time.LocalDateTime;

@EntityListeners(value = CustomEntityListener.class)
public class CustomEntityListener {

    @PrePersist
    public void prePersist(Object object) {
        if(object instanceof User) {
            ((User) object).setCreatedAt(LocalDateTime.now());
            ((User) object).setUpdatedAt(LocalDateTime.now());
        }
    }

    @PreUpdate
    public void preUpdate(Object object) {
        if(object instanceof User) {
            ((User) object).setUpdatedAt(LocalDateTime.now());
        }
    }
}

 

User.java

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
@EntityListeners(value = CustomEntityListener.class)
public class User {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private String email;

    @Column(updatable = false)
    private LocalDateTime createdAt;

    private LocalDateTime updatedAt;

}

테스트

import com.example.jpaexample.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    void userTest() {
        User user = User.builder()
                .name("Steve")
                .email("test@test.com")
                .build();

        userRepository.save(user);

        System.out.println(userRepository.findAll());
    }

}

간단하게 테스트를 구현하여 실행해 보았다

User에 createdAt과 updatedAt 은 우리가 직접 넣어주지 않고 Listener를 통해 insert 전과 update 전에 넣어 주도록 만들었다 User 클래스의 EntityListener 어노테이션을 주석 처리했을 때와 안 했을 때의 결과를 확인해 보면 Listener 가 잘 동작하는 것을 확인할 수 있다

 

Listener를 사용할 Entity 객체에 EntityListener 어노테이션을 달아주면 된다 value 에는 {} 배열로 여러 개의 클래스를 넣어 줄 수 있다

 

여러 Entity 에 공통된 로직이 필요 할 경우 공통된 속성을 인터페이스로 만들어 사용하면 코드의 중복을 줄일 수 있다

728x90
반응형