Entity : RDB의 Table과 맵핑되는 객체
@Entity
@Table(name = "customers") // 지정하지 않을시 클래스명 사용
@Getter
@Setter
public class Customer {
@Id private long id; // pk 설정
private String firstName;
private String lastName;
}
EntityManagerFactory : Entity를 관리하는 EntityManager를 생산하는 팩토리. Thread-safe하다
EntityManager : Entity를 저장하고, 수정하고, 삭제하고, 조회하는등 Entity와 관련된 모든 일을 처리한다. Thread-safe하지 않다
하나의 팩토리를 만들고 요청별로 매니저를 생성하는 방식으로 작동된다. 엔티티 매니저는 트랙잭션을 시작(BEGIN)할때 커넥션 풀에서 커넥션을 획득한다
JPA를 이용하는데 가장 중요한 요소
엔티티를 영구 저장하는 환경. 엔티티매니저는 엔티티를 영속성 컨텍스트에 보관하고 관리한다
논리적인 개념이다
키값으로 엔티티를 1차 캐시에서 관리하기 때문에 엔티티는 id값을 반드시 가져야한다
JPA는 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 DB에 flush한다
flush는 영속성 컨텍스트의 변경 내용을 DB에 동기화하는 작업이다
영속성 컨텍스트가 엔티티를 관리하므로 얻는 이점은 다음과 같다
보통 트랜잭션 단위로 사용하기 때문에, 하나의 데이터베이스 트랜잭션 종료시 영속성 컨택스트도 종료된다
영속성 컨텍스트와 전혀 관계없는 상태
Customer customer = new Customer();
customer.setId(1L);
customer.setFirstName("Sangmin");
customer.setLastName("Lee");
영속성 컨텍스트에 관리된 상태
// 영속성 컨텍스트 생성
EntityManager em = new EntityManager();
em.persist(customer);
영속성 컨텍스트에 저장되었다가 분리된 상태
em.detach(customer); // 영속 상태 엔티티를 분리
em.clear(); // 영속 상태 모든 엔티티를 분리
em.close(); // 영속성 컨텍스트 종료
삭제된 상태
// customer 엔티티를 영속성 컨텍스트에서 분리하고 DB에서도 삭제
em.remove(customer);
// Given customerA = new Customer(1L); // id = 1 customerB = new Customer(2L); // id = 2
// EntityManagerFactory에서 엔티티 매니저 생성
EntityManager em = emf.createEntityManager();
// 트랜잭션 획득
EntityTransaction transaction = em.getTransaction();
transaction.begin();
// 영속성 컨텍스트에 등록하고 1차 캐시와 쓰기 지연 저장소에 저장
em.persist(customerA);
// 트랜잭션이 커밋되면 DB에 트랜잭션 실행
transaction.commit();
EntityManager em = emf.createEntityManager();
EntityTransaction transaction - em.gtTransaction();
transaction.begin();
em.persist(customerA); // 1차 캐시에 customerA 존재
transaction.commit();
// 1차 캐시에서 customerA 조회
// DB로 쿼리가 발생하지 않음
Customer customer = em.find(Customer.class, 1L);
EntityManager em = emf.createEntityManager();
EntityTransaction transaction - em.gtTransaction();
transaction.begin();
em.persist(customerB);
transaction.commit();
// 영속성 컨텍스트 초기화
em.clear(); // 1차 캐시에 customerB 존재 X
// DB에서 customerB 조회
// customerB를 조회하며 1차 캐시에도 저장함
Customer customer = em.find(Customer.class, 2L);
// 1차 캐시에서 조회
Customer entity = em.find(Customer.class, 2L);
// customerA 영속화 되어있을 때
transaction.begin();
Customer customer = em.find(Customer.class, 1L);
customer.setFirstName("Sangmin");
customer.setLastName("Lee");
// flush() 호출 시 변경사항을 감지하고 UPDATE 쿼리를 수행한다
transaction.commit();
// customerA가 영속화 되어있을 때
transaction.begin();
Customer customer = em.find(Customer.class, 1L);
em.remove(customer);
transaction.commit();