반응형
history 기능을 사용할 때 유용하다
history를 담을 객체를 새로 생성 (원본과 동일하게 선언)
package com.example.bookmanager.domain;
import com.example.bookmanager.domain.listener.Auditable;
import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.time.LocalDateTime;
@Data
// 상속받은 BaseEntity를 사용하기 위해서 ToString, EqualsAndHashCode 재정의
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Entity
@NoArgsConstructor
// 자동으로 생성날짜, 수정날짜를 입력해주기 위해서 선언
//@EntityListeners(value = MyEntityListener.class)
// 공통 클래스 사용
//@EntityListeners(value = AuditingEntityListener.class)
// User객체에 History를 저장할 객체 생성
// BaseEntity를 상속받아 그 안에 있는 설정들을 사용할 수 있다.
public class UserHistory extends BaseEntity {
@Id
@GeneratedValue
// @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NonNull
private String name;
@NonNull
private String email;
// update 할 경우 값을 제외하도록 설정
// @Column(updatable = false)
// 자동으로 해당값을 넣어준다.
// @CreatedDate
// private LocalDateTime createdAt;
// 자동으로 해당값을 넣어준다.
// @LastModifiedDate
// private LocalDateTime updatedAt;
}
공통으로 수정한 날짜와 생성한 날짜를 처리해줄 BaseEntity를 생성
package com.example.bookmanager.domain;
import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
// 공통으로 사용할 수정날짜, 생성날짜를 자동으로 처리해줄 Entity 선언
@EntityListeners(value = AuditingEntityListener.class)
// get, set 선언
@Data
// 해당 클래스를 상속받는 클래스에 현재 변수를 사용할 수 있도록 해주는 어노테이션
@MappedSuperclass
public class BaseEntity {
@Column(updatable = false)
// jpa에서 기본적으로 선언된 기능을 사용
@CreatedDate
private LocalDateTime createdAt;
// jpa에서 기본적으로 선언된 기능을 사용
@LastModifiedDate
private LocalDateTime updatedAt;
}
history에 관한 jpa를 사용하기 위한 repository 생성
package com.example.bookmanager.repository;
import com.example.bookmanager.domain.UserHistory;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserHistoryRepository extends JpaRepository<UserHistory, Long> {
}
프로젝트 메인 클래스에 @EnableJpaAuditing(Auditing을 사용하겠다는 선언) 어노테이션 선언
JPA 엔티티 작성 - JPA Auddit 적용
실무에서 엔티티를 생성하다보면 auddit(감사) 목적으로 거의 모든 엔티티에 들어가는 필드(컬럼)들이 있다. 일일이 작성하기 매우 귀찮은데.. Spring Data Auddit 기능을 활용하여 귀찮을 일을 줄일 수
velog.io
package com.example.bookmanager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication
@EnableJpaAuditing
public class BookmanagerApplication {
public static void main(String[] args) {
SpringApplication.run(BookmanagerApplication.class, args);
}
}
원본 DB에 데이터가 생성, 수정되었을때 처리해주기 위한 클래스 생성
package com.example.bookmanager.domain.listener;
import com.example.bookmanager.domain.User;
import com.example.bookmanager.domain.UserHistory;
import com.example.bookmanager.repository.UserHistoryRepository;
import com.example.bookmanager.support.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
// Autowired를 사용할 경우 spring bean 등록을 진행해야 하기 때문에 Component 어노테이션을 사용한다.
//@Component
public class UserEntityListener {
// @Autowired
// private UserHistoryRepository userHistoryRepository;
// 업데이트, 생성를 진행할 경우 자동으로 history에 저장되도록 설정
@PreUpdate
@PrePersist
public void prePersistAndPreUpdate(Object o) {
// UserHistoryRepository의 bean을 가져온다.
UserHistoryRepository userHistoryRepository = BeanUtils.getBean(UserHistoryRepository.class);
User user = (User) o;
UserHistory userHistory = new UserHistory();
userHistory.setId(user.getId());
userHistory.setName(user.getName());
userHistory.setEmail(user.getEmail());
userHistoryRepository.save(userHistory);
}
}
위 코드가 정상적으로 동작하기 위해서는 Repository에 bean값을 가져와야하기 때문에 그 기능을 사용하게 해 줄 클래스 생성
package com.example.bookmanager.support;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
// Bean 클래스를 생성해주기위한 클래스
@Component
public class BeanUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
BeanUtils.applicationContext = applicationContext;
}
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
}
User 클래스에 history기능을 사용하기 위해서 @EntityListeners 어노테이션에 추가
//공통 Entity 사용
@EntityListeners(value = {AuditingEntityListener.class, UserEntityListener.class})
//@Table(name = "user", indexes = {@Index(columnList = "name")}, uniqueConstraints = {@UniqueConstraint(columnNames = {"email"})})
public class User {
테스트 코드
@Autowired
private UserHistoryRepository userHistoryRepository;
@Test
void userHistoryTest(){
User user = new User();
user.setEmail("martin-new@naver.com");
user.setName("martin-new");
userRepository.save(user);
// 업데이트 발생
user.setName("martin-new-new");
userRepository.save(user);
userHistoryRepository.findAll().forEach(System.out::println);
}
처리 결과(정상적으로 history에 값이 입력되는 것을 확인 할 수 있다.)
반응형
'Spring > JPA' 카테고리의 다른 글
연관 관계 설정 -1 (0) | 2021.07.24 |
---|---|
연관관계, ERD (0) | 2021.07.24 |
Entity Listener (0) | 2021.07.18 |
Enum 사용 예제 (0) | 2021.07.18 |
Entity 기본 속성 (0) | 2021.07.18 |