영속성 컨텍스트란?
영속성 컨텍스트는 엔티티를 영구적으로 저장하는 환경으로 엔티티 매니저로 엔티티를 저장하거나 조회시 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리하게 됩니다.
엔티티매니저 팩토리 : 엔티티 매니저를 만드는 곳 생성비용이 커서 한 개만 만들어 애플리케이션 전체에서 공유합니다. 여러 스레드가 접근해도 안전합니다.
엔티티 매니저 : 엔티티를 저장하고, 수정하고, 삭제하고 조회하는 등 엔티티와 관련된 일을 처리합니다. 또한 영속성 컨텍스트를 통해 데이터의 상태 변화를 감지하고 필요한 쿼리를 자동으로 수행해줍니다.
엔티티의 생명주기
비영속 : 엔티티 객체를 생성한 상태
Member member = new Member();
// 아직 저장되지 않음, 영속성 컨텍스트나 데이터베이스와는 아직 관련이 없다.
영속 : 영속성 컨텍스트에 의해 관리되는 상태
em.persist(member);
// 엔티티 매니저를 통해 엔티티를 영속성 컨텍스트에 저장
준영속 : 영속 상태의 엔티티를 영속성 컨텍스트가 관리하지 않게되는 상태
em.detach(member);
// em.close() , em.clear()를 호출해도 준영속상태가 된다.
삭제 : 엔티티를 영속성 컨텍스트와 db에서 삭제
em.remove(member);
영속성 컨텍스트의 특징과 장점
1차 캐시 기능 제공
영속성 컨텍스트는 1차캐시라는 내부 캐시를 제공하는데 영속상태의 엔티티가 키(@Id로 매핑한 식별자) 값(엔티티의 인스 턴스)의 형태로 저장됩니다.
Memeber member = new Member();
member.setId("member1");
member.setUsername("하하");
em.persist(member); //영속상태로 만든다 컨택스트 안 1차캐시에 회원 엔티티가 저장된다.
엔티티를 조회하게 되면 가장먼저 1차캐시에서 엔티티를 찾고 엔티티가 1차캐시에 존재하지 않으면 데이터베이스에서 조회하게 됩니다.
1. 1차캐시에 존재하는 경우
Member findmember1 = em.find(Member.class, "member1");
2. 1차캐시에 존재하지 않는 경우
Member findMember2 = em.find(Member.class, "Member2")
1차캐시에 엔티티가 없으면 엔티티 매니저는 데이터 베이스 조회를 통회 엔티티를 생성합니다. 그리고 1차캐시에 저장한 후 영속상태의 엔티티를 반환하게 됩니다.
이제 이 member1과 member2를 조회할 경우에는 1차 캐시에서 바로 불러올 수 있어 성능상 이점을 누릴 수 있습니다.
영속 엔티티의 동일성 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b);
영속성 컨텍스트는 1차캐시에 있는 같은 인스턴스를 반환하기 때문에 동일성이 보장됩니다.
트랜잭션 기능을 제공하는 쓰기지연
엔티티 매니저는 트랜잭션을 커밋하기 직전까지 데이터베이스에 엔티티를 저장하지 않고 내부에 존재하는 쿼리 저장소에 SQL을 모아두고 트랜잭션을 커밋할 때 모아둔 쿼리를 데이터베이스에 보내는데 이것을 쓰기 지연이라고 합니다.
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
em.persist(memberA);
em.persist(memberB);
//쿼리 저장소에 쿼리를 보관
//커밋하는 순간 쿼리를 보낸다.
transaction.commit();
이 기능을 잘 활용하면 모아둔 등록 쿼리를 데이터베이스에 한번에 전달해 성능을 최적화할 수 있습니다.
변경 감지
JPA로 엔티티를 수정하는 경우는 엔티티를 조회해서 데이터반 변경하면 되는데 엔티티의 변경 사항을 데이터베이스에 자동으로 반영해주는 것을 변경 감지라고 합니다.
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
Mamber memberA = em.find(Member.class, "MemberA");
memberA.setUsername("호호호");
memberB.setAge(10);
transaction.commit();
JPA는 영속성 컨텍스트 보관시 최초의 상태를 복사해 저장해두게 됩니다,(스냅샷) 그리고 플러시 시점에 스냅샷과 엔티티를 비교해 변경된 엔티티를 찾습니다.
지연로딩
JPA에서는 데이터를 조회할 때 즉시 로딩(EAGER)과 지연 로딩(LAZY) 두 가지 방식이 존재합니다. 즉시 로딩(EAGER) 방식은 즉시 로딩은 데이터를 조회할 때 연관된 데이터까지 한 번에 불러오고 지연 로딩(LAZY) 방식은 필요한 시점에 연관된 데이터를 불러옵니다.
'Backend > JPA' 카테고리의 다른 글
[JPA] 프록시, 지연로딩, 즉시로딩은 무엇인가? (0) | 2024.06.17 |
---|---|
[JPA] Spring Data JPA란? (0) | 2024.06.12 |
[JPA] JPA란 무엇일까? (0) | 2023.07.17 |
[JPA] @JpaDataTest에서 Auditing 기능 사용하기 (0) | 2023.06.23 |
[JPA] JPA Auditing 기능을 이용한 생성, 수정일자 자동화 (0) | 2023.06.19 |