엔티티 매니저 팩토리와 엔티티 매니저
영속성 컨텍스트(JPA를 이해하는데 가장 중요 용어)
'엔티티를 영구 저장하는 환경'이라는 뜻을 가진다.
EntityManager.persist(entity)
: 영속성 컨텍스트를 통해 해당 엔티티를 영속화한다. 영속성 컨텍스트에 저장한다는 의미다.
엔티티 매니저를 통해 영속성 컨텍스트에 접근한다.
엔티티 생명주기
em.persist(entity)
)비영속 상태란?
//비영속(엔티티를 생성한 상태)
Member member = new Member();
member.setId(1L);
member.setName("helloA");
영속 상태란?
//엔티티를 영속
Member member = new Member();
member.setId(1L);
member.setName("helloA");
em.persist(member);
영속성 컨텍스트 이점? 애플리케이션-db 사이에 위치한다.
1차 캐시
1차 캐시에서 조회해보고 없다면 db를 조회해서 1차 캐시에 저장하고 반환한다.
고객 요청을 응답하는 과정에서 데이터베이스 하나의 트랜잭션 안에서만 사용되고 반환되므로 크게 이점은 아니다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); // "hello"는 Persistence Unit의 이름과 일치해야 합니다.
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); //트랜잭션 시작
try{
//code 작성
//비영속
Member member = new Member();
member.setId(101L);
member.setName("helloA");
em.persist(member);
//findMember.setName("HelloJPA");
// JPA를 통해 엔티티를 가져오면, 엔티티 변경이 감지되면 커밋되기 직전에 update 쿼리가 나간다.
System.out.println("Member 101 : "+em.find(Member.class, 101L));
System.out.println("Member 101 : "+em.find(Member.class, 101L));
tx.commit();
}catch(Exception e){
tx.rollback();
}finally {
em.close();
}
emf.close();
-> select 문이 하나만 나가는 이유 : 1차 캐시에 저장된다.
동일성 보장
Member member = em.find(Member.class, 101L);
Member member1 = em.find(Member.class, 101L);
System.out.println(member == member1); //true
트랜잭션을 지원하는 쓰기 지연
em.persist
가 계속 적혀있어도 커밋하는 순간 한번에 트랜잭션이 일어난다.변경 감지(엔티티 수정)
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); // "hello"는 Persistence Unit의 이름과 일치해야 합니다.
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); //트랜잭션 시작
try{
// Member member1 = new Member(150L, "A");
// Member member2 = new Member(160L, "A");
// em.persist(member1);
// em.persist(member2);
Member member = em.find(Member.class, 150L);
member.setName("zzzz");
//이 코드는 써서는 안된다. em.persist(member); setter를 통해서 update query가 나간다.
System.out.println("=================="); // persist insert query보다 먼저 출력된다.
tx.commit(); //트랜잭션 커밋
}catch(Exception e){
tx.rollback();
}finally {
em.close();
}
emf.close();
객체를 수정했을때 왜 em.persist를 하지 않아도 되는가?
flush()
발생..따라서 JPA에서는 값이 바뀌면 영속 컨텍스트 내에 스냅샷과 비교해서 변경 감지.. UPDATE Query를 DB에 보내고 트랜잭션 커밋을 수행한다.
플러시(영속성 컨텍스트의 변경내용을 DB에 반영)
준영속 상태
em.detach(member)
, em.clear()