Listener: 어떠한 동작하는 것을 기다리다가 동작하게 되면 이벤트를 동작 해주는 것

Entity Listener: Entity 객체가 어떠한 동작을 하는지 기다리다가 이벤트를 동작 시키는 것

 

참고 사이트: https://erim1005.tistory.com/entry/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B3%80%EA%B2%BD-%EC%95%8C%EB%A6%BC-EntityListeners

 

데이터 변경 알림 - @EntityListeners

spring 의 data-jpa 사용시 데이터 변경시 알림을 받는 방법이 있다. EntityListener 클래스를 만들고 public class DataDtoListener { @PostLoad public void postLoad(DataDto dto) { log.info("post load: {}",..

erim1005.tistory.com

 

테스트 진행을 위한 코드 입력

user 객체에 어노테이션을 적용한 메소드 추가

@PrePersist
public void prePersist(){
    System.out.println(">>> prePersist");
    // 사용자가 입력을 안해주어도 자동으로 현재 날짜를 입력하도록 설정
    this.createdAt = LocalDateTime.now();
    this.updatedAt = LocalDateTime.now();
}

@PostPersist
public void postPersist(){
    System.out.println(">>> postPersist");
}

@PreUpdate
public void preUpdate(){
    System.out.println(">>> preUpdate");
    // Update를 진행할 때 자동으로 update를 진행한 날짜를 입력하도록 설정
    this.updatedAt = LocalDateTime.now();
}

@PostUpdate
public void postUpdate(){
    System.out.println(">>> postUpdate");
}

@PreRemove
public void preRemove(){
    System.out.println(">>> preRemove");
}

@PostRemove
public void postRemove(){
    System.out.println(">>> postRemove");
}

@PostLoad
public void postLoad(){
    System.out.println(">>> postLoad");
}

테스트 코드 작성

    @Test
    void listenerTest(){
        Dto();
        User user = new User();
        user.setEmail("martin2@fastcapmus.com");
        user.setName("martin");

        userRepository.save(user);

        User user2 = userRepository.findById(1L).orElseThrow(RuntimeException::new);
        user2.setName("marrrrrrrtin");;
        userRepository.save(user2);
        userRepository.deleteById(4L);
    }

확인

저장하기 전과 저장한 후에 호출

조회 후에 호출

 

업데이트 전과 후에 호출

삭제 전 후에 호출

 

주로 사용자가 프로그램상에서 새로 데이터를 생성하거나 수정을 하였을때 날짜를 자동으로 입력해줄 때 사용할 수 있다.

테스트 코드

    @Test
    void prePersistTest() {
        User user = new User();
        user.setEmail("martin2@fastcampus.com");
        user.setName("martin");
//        user.setCreatedAt(LocalDateTime.now());
//        user.setUpdatedAt(LocalDateTime.now());

        userRepository.save(user);
        System.out.println(userRepository.findByEmail("martin2@fastcampus.com"));
    }

    @Test
    void preUpdateTest() {
        Dto();
        User user = userRepository.findById(1L).orElseThrow(RuntimeException::new);

        System.out.println("as-is: " + user);

        user.setName("martin22");
        userRepository.save(user);

        System.out.println("to-be: " + userRepository.findAll().get(0));
    }

 

여러군데에서 적용하기 위해서는 아래와 같이 인터페이스를 따로 만들어서 적용 시킬수 있다.

인터페이스 생성

package com.example.bookmanager.domain;

import java.time.LocalDateTime;

public interface Auditable {
    LocalDateTime getCreatedAt();
    LocalDateTime getUpdatedAt();

    void setCreatedAt(LocalDateTime createdAt);
    void setUpdatedAt(LocalDateTime updatedAt);
}

Entity Listener를 선언한 클래스 작성

package com.example.bookmanager.domain;

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

public class MyEntityListener {
    @PrePersist
    public void prePersist(Object o) {
        // 전달받은 매개변수가 Auditable 클래스로 형변환해도 괜찮은지 확인
        if (o instanceof Auditable){
            ((Auditable) o).setCreatedAt(LocalDateTime.now());
            ((Auditable) o).setUpdatedAt(LocalDateTime.now());
        }
    }

    @PreUpdate
    public void preUpdated(Object o){
        // 전달받은 매개변수가 Auditable 클래스로 형변환해도 괜찮은지 확인
        if (o instanceof Auditable){
            ((Auditable) o).setUpdatedAt(LocalDateTime.now());
        }
    }
}

사용할 Listener를 적용할 객체  클래스 작성

@EntityListeners(value = MyEntityListener.class) 를 선언하여 작성한 클래스가 적용될 수 있도록 설정한다.

package com.example.bookmanager.domain;

import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
@Data
@Builder
@Entity
@EntityListeners(value = MyEntityListener.class)
//@Table(name = "user", indexes = {@Index(columnList = "name")}, uniqueConstraints = {@UniqueConstraint(columnNames = {"email"})})
public class User {
    @Id
    @GeneratedValue
//    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NonNull
    private String name;

    @NonNull
    private String email;

    // update 할 경우 값을 제외하도록 설정
    @Column(updatable = false)
    private LocalDateTime createdAt;

    private LocalDateTime updatedAt;

    @Enumerated(value = EnumType.STRING)
    private Gender gender;
//    @Transient
//    private String testData;

    public User(String name, String email, LocalDateTime creDate, LocalDateTime upDate) {
        this.name = name;
        this.email = email;
        this.createdAt = creDate;
        this.updatedAt = upDate;
    }

    //@OneToMany(fetch = FetchType.EAGER)
    //private List<Address> address;

    // Entity Listener 이벤트 정의 및 동작 시점 확인
    @PrePersist
    public void prePersist(){
        System.out.println(">>> prePersist");
        // 사용자가 입력을 안해주어도 자동으로 현재 날짜를 입력하도록 설정
        this.createdAt = LocalDateTime.now();
        this.updatedAt = LocalDateTime.now();
    }

    @PostPersist
    public void postPersist(){
        System.out.println(">>> postPersist");
    }

    @PreUpdate
    public void preUpdate(){
        System.out.println(">>> preUpdate");
        // Update를 진행할 때 자동으로 update를 진행한 날짜를 입력하도록 설정
        this.updatedAt = LocalDateTime.now();
    }

    @PostUpdate
    public void postUpdate(){
        System.out.println(">>> postUpdate");
    }

    @PreRemove
    public void preRemove(){
        System.out.println(">>> preRemove");
    }

    @PostRemove
    public void postRemove(){
        System.out.println(">>> postRemove");
    }

    @PostLoad
    public void postLoad(){
        System.out.println(">>> postLoad");
    }
}

 

테스트 코드 작성

package com.example.bookmanager.repository;

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

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class BookRepositoryTest {

    @Autowired
    private BookRepository bookRepository;

    @Test
    void bookTst(){
        Book book = new Book();
        book.setName("Jpa 공부");
        book.setAuthor("여기저기");

        bookRepository.save(book);
        System.out.println(bookRepository.findAll());
    }
}

확인

 

수정한 날짜와 생성날짜를 따로 입력하지 않았지만 자동으로 입력된 것을 확인할 수 있다.

 

'Spring > JPA' 카테고리의 다른 글

연관관계, ERD  (0) 2021.07.24
Entity Listener 사용 예제 2  (0) 2021.07.18
Enum 사용 예제  (0) 2021.07.18
Entity 기본 속성  (0) 2021.07.18
Query Method 예제 - 5(페이징 처리)  (0) 2021.07.17

+ Recent posts