엔티티 매니저 팩토리와 엔티티 매니저
EntityManagerFactory
- Entity를 관리하는 EntityManager 를 생산하는 공장
- ThreadSafe 하다.
EntityManager
- EntityManager는 Entity를 저장, 수정, 조회, 삭제 (CRUD)등 Entity와 관련된 모든 일을 처리
- ThreadSafe 하지 않음
- 여러 Thread에서 동시에 접근 할 경우 동시성 이슈가 발생할 수 있다.

영속성 컨텍스트
- 엔티티를 영구 저장(영속화)하는 환경
em.persist(entity);

- 논리적인 개념이다.
- 엔티티 매니저를 통해서 영속성 컨텍스트에 접근
영속성 컨텍스트의 특징
- 식별자 값
- 영속성 컨텍스트 안에서 관리되는 엔티티는 식별자 값을 반드시 가져야 한다.
- key-value로 엔티티를 관리하기 때문이다.
- 영속성 컨텍스트와 DB 저장
- JPA는 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 DB에 반영한다. (flush)
- 플러시(flush)는 영속성 컨텍스트의 변경내용을 db에 동기화 하는 작업이다.
- 영속성 컨텍스트가 엔티티를 관리함으로 얻는 이점
- 1차 캐시
- 동일성 보장
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
- 지연 로딩
엔티티의 생명주기
- 비영속 (new/transient)
Member member = new Member();
- 영속(managed) - 영속성 컨텍스트에 추가
Member member = new Member(); //member 객체가 영속성 컨텍스트에서 관리된다. em.persist(member);
- 준영속(detached) - 영속성 컨텍스트에서 분리
Member member = new Member(); member.setId(1L); //영속상태의 customer객체를 영속성컨텍스트에서 분리한다. em.detach(member); //영속상태의 모든 객체를 영속성컨텍스트에서 분리한다. em.clear(); //영속성 컨텍스트를 종료한다. em.close();
- 삭제(removed) - db에서 delete
//영속성 컨텍스트에서 분리하고 db에서도 삭제한다. em.remove(member);
영속성 컨텍스트의 이점
1차 캐시 - 한 트랙젝션 내에서의 캐시기능
Member member = new Member(); member.setId(102L); member.setName("HelloA"); em.persist(member); Member findMember = em.find(Member.class, 102L); System.out.println("findMember.getId() = " + findMember.getId()); System.out.println("findMember.getName() = " + findMember.getName()); tx.commit();
→ select 쿼리 안나감!!!!!
이미 102번 멤버가 있을때
Member findMember1 = em.find(Member.class, 102L); System.out.println("findMember1 = " + findMember1); Member findMember2 = em.find(Member.class, 102L); System.out.println("findMember2 = " + findMember2); tx.commit();
→ select 쿼리 한방!!
심지어 findMember의 동일성 보장!!
findMember1 = Member@1894e40d findMember2 = Member@1894e40d
트랜잭션을 지원하는 쓰기 지연
em.persist(memberA); em.persist(memberB); tx.commit(); // em.flush()-> 여기서 Insert Query 두방!!


변경 감지
데이터 수정을 컬렉션처럼! dirty checking!

커밋 직전 (flush하면) 앤티티와 스냅샷을 비교
JPA는 엔티티를 영속성 컨텍스트에 보관할 때 최초 상태를 복사해서 저장해 두는데 이것을 스냅샷이라 한다. 그리고 플러시 시점에 스냅샷과 엔티티를 비교해서 변경된 엔티티를 찾는다. 만약 스냅샷과 비교하여 변경된 내용이 있을 경우 update Query를 수행한다. (변경 감지는 영속성 컨텍스트가 관리하는 영속 상태의 엔티티에만 적용이 된다.)
@)See Also
플러시
영속성 컨텍스트의 변경 내용을 DB에 반영
플러시 →
- 변경감지
- 변경된 엔티티의 수정 쿼리를 쓰기 지연 SQL저장소에 등록
- 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송 (등록, 수정, 삭제)
- 1차 캐시는 유지된다 (영속성 컨텍스를 비우는 것이 아님)
em.flush()
- 직접 실행tx.commit()
- 자동 실행jpql 쿼리 - 자동 실행
준영속 상태
- 영속 → 준영속
- 영속성 컨텍스트에서 분리
- 영속성 컨텍스트의 기능 사용안함
em.detach(entity)
- 특정 엔티티를 영속 상태에서 제거
em.clear()
- 영속성 컨텍스트를 완전히 초기화em.close()
- 영속성 컨텍스트 종료원래
요청 시작 : db connection 시작
→ 요청 끝 : db connection 종료
OSIV false
@Transactional
시작 : db connection 시작→
@Transactional
탈출 : db connection 종료OSIV true
@Transactional
시작 db connection 시작→ 요청 끝 : db connection 종료