[JPA] JPA 변경 감지를 이용하여 상태 변경을 반영
1. JPA의 변경감지
1) 정의
JPA 에서 변경 감지는 엔티티 객체의 상태를 추적하여, 변경된 Entity 를 데이터베이스에 자동으로 반영하는 메커니즘입니다.
2) 작동 원리
① JPA 는 EntityManager 를 사용하여 엔티티를 관리한다.
- EntityManager 는 엔티티를 영속성 컨텍스트에 저장하며, 이후에 엔티티를 조회하거나 수정할 수 있다.
② 이때 영속성 컨텍스트는 EntityManager 가 관리하는 엔티티의 상태를 추적하고, 변경된 엔티티를 데이터베이스에 자동으로 반영하는 기능을 제공한다.
- EntityManager 에서 영속성 컨텍스트의 flush 메서드를 호출하면, 영속성 컨텍스트에서 변경된 엔티티를 데이터베이스에 반영
③ 영속성 컨텍스트는 엔티티의 변경을 감지하기 위해 Dirty Checking 기법을 사용한다.
- Dirty Checking 은 영속성 컨텍스트에서 엔티티의 상태를 추적하고, 엔티티의 값이 변경되면 변경된 값을 추적하여 Dirty Flag 를 설정
- 이후에 flush 메서드를 호출하면, 영속성 컨텍스트는 Dirty Flag 가 설정된 엔티티를 데이터베이스에 자동으로 반영
참고
Dirty Checking : 엔티티의 상태를 추적하여, 상태가 변경된 엔티티를 자동으로 감지하고 데이터베이스에 자동으로 반영
∴ JPA의 변경 감지는 Dirty Checking 기법을 사용해 엔티티의 상태를 추적하고 데이터베이스에 자동으로 반영하는 기능을 제공
2. 예제 코드
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 엔티티 조회
Member member = em.find(Member.class, 1L);
// 엔티티 수정
member.setName("Mery");
// 트랜잭션 커밋
em.getTransaction().commit();
em.close();
emf.close();
출처: 자바 ORM 표준 JPA 프로그래밍
- 코드에서 EntityManagerFactory 를 생성하고 EntityManager 를 생성
- EntityManagerFactory 는 애플리케이션의 전체 라이프사이클 동안 한 번만 생성되며, EntityManager 는 각각의 트랜잭션에서 사용된다
- Member member = em.find(Member.class, 1L); : id 가 1인 엔티티를 조회한다.
- member.setName("Mery"); : Member 엔티티의 name 을 Mery로 변경한다
-> 이때, 영속성 컨텍스트에서는 Dirty Checking 기법을 사용해 엔티티의 상태를 추적한다- 변경된 name 속성은 Dirty Flag 가 설정된다
- 이제 EntityManager 의 트랜잭션을 커밋한다.
-> 이때, 영속성 컨텍스트는 Dirty Flag 가 설정된 Member 엔티티를 데이터베이스에 자동으로 반영한다.
JPA에서는 엔티티를 영속성 컨텍스트에 저장하면, 해당 엔티티의 상태 변경을 추적한다. 이후에, 엔티티의 상태가 변경되면 Dirty Flag 가 설정됩니다.
JPA는 Dirty Flag 가 설정된 엔티티를 자동으로 감지하고, 트랜잭션을 커밋할 때 데이터베이스에 자동으로 반영합니다.
따라서, 엔티티의 값을 변경하면, 영속성 컨텍스트에서 자동으로 변경 감지 기능이 동작하며, 변경된 엔티티를 따로 save 메서드를 호출하지 않아도 자동으로 데이터베이스에 반영할 수 있습니다.
3. JPA 변경 감지 적용 코드
모카콩 프로젝트(https://github.com/mocacong/Mocacong-Backend) 에서 updateCafeReviewDetails 메서드 코드 일부분입니다.
해당 코드는 엔티티 Score , Review 에 대해 값을 수정하는 코드입니다. 여기서 DatabaseCleaner 에 등록된 EntityManager 덕분에 JPA의 변경 감지가 자동으로 일어나기 때문에 따로 save 메서드를 호출하지 않아도 갱신된 값으로 데이터베이스에 반영됩니다.
참고
변경 감지 기능을 사용하고 싶다면 EntityManagerFactory 는 만들 필요가 없고 EntityManager 를 사용하면 된다.