영속성 컨텍스트
EntityManagerFactory에서 고객의 요청이 있을 때 마다 EntityManager를 생성한다. 이렇게 생성된 EntityManager는 커넥션풀에서 커넥션을 가져와 사용한다.
EntityManagerFactory는 어플리케이션 통틀어서 단 하나!
EntityManager는 쓰레드간 공유하면 안된다.
영속성 컨텍스트
- "엔티티를 영구 저장"하는 환경이라는 뜻.
- EntityManager.persist(entity)
- entity를 DB에 저장하는 것이 아니라, 영속성컨텍스트에 저장한다.
- EntityManager.persist(entity)
- 엔티티 매니저를 통해 영속성컨텍스트에 접근한다.
- 트랜잭션이 끝나면 영속컨텍스트 또한 종료된다.
엔티티의 생명주기
- 비영속(new / transient)
- 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
- 영속(managed)
- 영속성 컨텍스트에 관리되는 상태
- 준영속(detached)
- 영속성컨텍스트에 저장되었다가 분리된 상태
- 삭제(removed)
- 삭제된 상태
비영속
// 객체를 생성한 상태(비영속)
Member member = new Member();
member.setId(1L);
member.setName("memberA");
영속
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(member)
- 객체를 저장한 상태(영속). 디비에 저장된 상태 아니다.
- 트랜잭션이 커밋돼야 디비에 저장된다.
준영속
em.detach(member); //영속상태인 member를 영속성컨텍스트에서 분리했다.
삭제
em.remove(member); // 객체를 삭제한 상태.
영속성 컨텍스트의 장점
- 1차캐시
- persist하면 1차캐시에 먼저 저장.
- find를 하면 DB에 바로 접근하는 것이 아닌, 1차캐시에서 먼저 찾는다.
- 만약 1차캐시에 없으면 그제서야 DB에 접근해서 조회하게 되는데, 조회결과값을 1차캐시에 저장하고 반환한다.
Member member = new Member(); member.setId(2L); member.setName("memberB");
- 만약 1차캐시에 없으면 그제서야 DB에 접근해서 조회하게 되는데, 조회결과값을 1차캐시에 저장하고 반환한다.
em.persist(member);
Member findMember = em.find(Member.class, 2L);
System.out.println("findMember = " + findMember.getName());
- `SELECT` 쿼리 안나간다! 왜? 1차캐시에 있기때문에
- 동일성 보장
- 같은 트랜잭션 안이어야 함.
````java
Member findMember1 = em.find(Member.class, 2L);
Member findMember2 = em.find(Member.class, 2L)l
System.out.println(member1 == member2) //true
- 트랜잭션을 지원하는 쓰기 지연
EntityTransaction tx = em.getTransaction(); tx.begin();
//persist하면 1차캐시에 저장함과 동시에,
//영속성 컨텍스트의 쓰기지연SQL저장소에 INSERT SQL저장
em.persist(memberA);
em.persist(memberB);
//커밋하는 순간 Insert SQL 보낸다.
tx.commit();
- 변경감지(더티체킹)
- 영속상태인 객체를 변경했다면 커밋시점에 변경됨.(persist 호출 불필요)
- 지연로딩
'JAVA > JPA' 카테고리의 다른 글
순수 JPA레포지토리의 페이징과 스프링 데이터 JPA레포지토리의 페이징. (0) | 2020.02.10 |
---|---|
연관관계의 주인 (0) | 2020.01.27 |
준영속 상태 (0) | 2020.01.16 |
플러시 (0) | 2020.01.16 |
모든 JPA작업은 트랜잭션 단위 안에서 일어나야한다. (0) | 2019.12.08 |