JPA에서 가장 중요한 2가지
EntityManagerFactory
에서 EntityManager
를 생성한다.EntityManger
는 내부적으로 커넥션풀을 사용하여 DB에 접근한다.EntityManager.persist(entity);
엔티티를 영속화 한다는 뜻
new Member();
영속성 컨텍스트에 관리되는 상태
Member member = new Member();
em.persist(member);
em.persist()
한 순간에 쿼리가 날아가지는 않는다. 커밋 시점에 쿼리가 날아간다.
em.detach(membr);
em.remove(member);
Member member = new Member();
//1차 캐시에 저장됨
em.persist(member);
//1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");
Member member = new Member();
member.setId(10L);
member.setName("helloC"); // 여기까지 비영속
em.persist(member); // 영속
Member findMember = em.find(Member.class, 10L); // 조회
System.out.println("findMember.getId()" + findMember.getId());
System.out.println("findMember.getName()" + findMember.getName());
결과 쿼리
findMember.getId() = 10
findMember.getName() = helloC
Hibernate:
/* insert hellojpa.Member */
insert
into
Member
(name, id)
values
(?, ?)
Insert 쿼리가 나가기 전에 엔티티를 조회하고 출력했다. 이는 DB가 아닌 1차 캐시에서 엔티티를 조회했다는 뜻이고 커밋 시점에 insert 쿼리가 나간 것이다. 조회 쿼리는 나가지도 않았다.
Member a = em.find(Member.class, 10L);
Member b = em.find(Member.class, 10L);
System.out.println(a == b); //동일성 비교 true
Member findMember = em.find(Member.class, 2L);
findMember.setName("JPA"); // 변경감지
persist
를 할 필요가 없다!
flush()
가 호출된다.flush()
호출 후 엔티티와 스냅샷을 비교한다.영속성 컨텍스트의 변경 내용을 데이터베이스에 반영
em.flush()
- 직접 호출em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
// 여기까지 insert 쿼리가 안나갔기 대문에 DB에 아무것도 없음
// 중간에 JPQL 실행, 모든 Member 조회
// 코드 로직 상 memberA, B, C가 조회되어야 함
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();
// 이런 경우 때문에 JPQL을 실행하면 flush가 강제적으로 일어남
em.setFlushMode(FlushModeType.COMMIT)
FlushModeType.AUTO
커밋이나 쿼리를 실행할 때 플러시 (기본값)FlushModeType.COMMIT
커밋할 때만 플러시em.detach(entity)
em.clear()
em.close()
// 조회하면 영속 상태 (1차 캐시에 저장)
Member findMember = em.find(Member.class, 2L);
findMember.setName("JPA study"); // 변경감지
// 준영속 상태
em.detach(findMember);
tx.commit();
//실행하면 select 쿼리만 나가고 커밋 시 변경 감지로 인한 update 쿼리는 나가지 않는다.