생성일: 2022년 3월 24일 오후 4:40
태그: JPA
저번시간에 흔하게 사용되는 것을 알아봤는데 조금더 알아보자 DB에 특정 데이터가 저장되면 다른 테이블에 추가적으로 저장시킨다.
먼저 추가적인 클래스와 Listener 및 interface를 만들어 주자
@Component
public class UserEntityListener {
@Autowired
UserHistoryRepository userHistoryRepository;
@PreUpdate
public void preUpdate(Object o){
User user = (User) o;
UserHistory userHistory = new UserHistory();
userHistory.setUserId(user.getId());
userHistory.setName(user.getName());
userHistory.setEmail(user.getEmail());
userHistoryRepository.save(userHistory);
}
}
====================interface=========================
public interface UserHistoryRepository extends JpaRepository<UserHistory,Long> {
}
위와 같이 만들어준 뒤 History 테이블도 간단하게 만들어 주자!
user공간에서 Test를 시행
@Autowired
UserHistoryRepository userHistoryRepository;
@Test
void userHistoryTest(){
User user =new User();
user.setEmail("martin@naver.com");
user.setName("martin");
userRepository.save(user);
user.setName("marrtin");
userRepository.save(user);
userHistoryRepository.findAll().forEach(System.out::println);
}
오류가 난다! —> userHistory 가 null로 나오면서 Entity클래스는 Bin을 주입받을 수 없기 때문
실제 IDE에서도 권장하질 않는다! —> bind를 가져오는 class를 만들자!
BeanUtils
@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);
}
}
위와 같이 만들고 가져올 때는
UserHistoryRepository userHistoryRepository = BeanUtils.*getBean*(UserHistoryRepository.class);
메소드 안에 위와 같이 생성 해주고, 기존 주입은 지워주자!
이후에 잘 저장이 된것을 확인했다!
Listener를 중복 사용 가능!
간단하게 저번시간에 createdAt updatedAt도 자동으로 넣어주는 구문을 추가로 History에 넣어줄 수도 있다!
근데 사용을 할때는 위와 같이 명시를 해줘야 한다!
하지만 이러한 기본적인 Listener 들은 Spring에서 기본적으로 제공!
BookApplication에서 어노테이션 추가 —>@EnableJpaAuditing
book 과 History / User 에 아래와 같이 class부분을 바꿔 주자!
마지막으로 별도의 어노테이션으로 명시를 해주자!
실행하면 똑같은 것을 볼 수 있다
실제 현업에서 사용되는 경우!
지금 현재 book,user,userHistory에 각각 @createdDate @LastModifiedDate가 사용되고 있다 이를 좀 다르게 바꿀 수 있다!
@Data
@MappedSuperclass
@EntityListeners(value = AuditingEntityListener.class)
public class BaseEntity {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
@MappedSuperclass —> 상위 클래스에 baseEntity의 컬럼을 포함시키겠다라는 말이된다.
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)