영속성 컨텍스트
엔티티에는 생명주기가 있다.
비영속(new/transient)
영속(managed)
준영속(detached)
삭제(removed)
try {
Member member = new Member();
member.setId(100L);
member.setName("HelloJPA"); // 여기까지는 비영속 상태
em.persist(member); // 여기서부터는 영속 상태, 그렇다고 db에 저장된 상태는 아니고 영속성 컨텍스트 안에서 관리만 되는 상태
tx.commit(); // 여기서 커밋을 해야 영속성 컨텍스트 안에서 관리되고 있는 데이터를 db 에 들어간다.
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
Member a = em.find(Member.class, “member1”);
Member b = em.find(Member.class, “member1”);
System.out.println(a == b); // 동일성 비교를 해보면 true
1차 캐시로 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공해준다.
Member member1 = new Member(150L, "A");
Member member2 = new Member(160L, "B"); // 비영속
em.persist(member1);
em.persist(member2); // 영속 상태이며, sql 에 데이터를 보내지 않는다.
// ================
tx.commit(); // commit 을 해야 영속성 컨텍스트에 벗어나 DB 에 insert sql 을 보내 저장한다.
Member member = em.find(Member.class, 150L);
member.setName("ZZZZ");
// em.persist(member);
commit 을 안해도 데이터베이스를 확인해보면 데이터가 변한걸 확인 할 수 있다.
여기서 초기화를 하면 값이 원래대로 돌아오고, commit 을 하게 된다면 변경된 값이 데이터베이스에 반영된다.
추가) remove 를 사용할 경우 삭제를 진행한다.
영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다.
플러시 발생 시
영속성 컨텍스트를 플러시하는 방법
Member member = new Member(200L, "member200");
em.persist(member); // 영속 상태
em.flush(); // 플러시 사용 시 바로 데이터베이스에 반영
em.commit;
플러시 정리
준영속 상태
(detach)
Member member = em.find(Member.class, 100L);
member.setName("AAAA"); // 영속 상태지만,
em.detach(member); // 내부에서 외부로 전환해서 준영속 상태가 된다.
(clear)
Member member = em.find(Member.class, 100L);
member.setName("AAAA"); // 영속 상태지만,
em.clear(); // 내부에 있는 영속 상태 값을 전부 초기화 한다.
(close)
Member member = em.find(Member.class, 100L);
member.setName("AAAA"); // 영속 상태지만,
em.close(); // 영속성 컨텍스트를 아예 닫아버려서 이것도 역시 준영속 상태가 된다.
이런 유용한 정보를 나눠주셔서 감사합니다.