웹 어플리케이션이 구동하는 시점에 EntityManagerFactory를 생성하고 사용자의 요청이 있을 때 EntitiyManager를 생성해 커넥션 풀을 사용해 db를 핸들링 한다.
// 비영속 (new, transient)
Member member = new Member();
member.setName("dh");
member.setId(1L);
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 트랜잭션 시작
// member 객체를 저장한 영속 상태 (managed)
em.persist(member);
// 회원 엔티티를 영속성 컨텍스트에서 분리한 준영속 상태
em.detach(member);
// 삭제 (remove)
em.remove(member);
Member member = new Member();
member.setName("대훈");
member.setId(1L);
em.persist(member);
Member findMember = em.find(Member.class, "1L");
Member member = new Member();
Member findMember = em.find(Member.class, "1L");
Member findMember2 = em.find(Member.class, "1L");
system.out.println(findMember == findmember2);
Member member = new Member(2L, "dh");
Member member2 = new Member(3L, "dh");
em.persist(member);
em.persist(member2); // 쓰기 지연 SQL 저장소에 저장
System.out.println("Lazy Loading");
tx.commit();
14:32:19.411 [main] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl - begin
Lazy Loading
14:32:19.412 [main] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl - committing
/* insert com.example.jpalearning.Member
*/ insert
into
Member
(USERNAME, MEMBER_ID)
values
(?, ?)
Hibernate:
/* insert com.example.jpalearning.Member
*/ insert
into
Member
(USERNAME, MEMBER_ID)
values
(?, ?)
14:36:07.150 [main] DEBUG org.hibernate.SQL -
/* insert com.example.jpalearning.Member
*/ insert
into
Member
(USERNAME, MEMBER_ID)
values
(?, ?)
Hibernate:
/* insert com.example.jpalearning.Member
*/ insert
into
Member
(USERNAME, MEMBER_ID)
values
(?, ?)org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl - Initiating JDBC connection release from afterTransaction
14:32:19.414 [main] DEBUG org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl - Initiating JDBC connection release from afterTransaction
14:32:19.414 [main] DEBUG org.hibernate.internal.SessionFactoryImpl - HHH000031: Closing
- 출력문 이후 쓰기 SQL 저장소에 저장된 쿼리들을 다 실행시켜 Database에 저장한다.
tx.begin();
Member findMember = em.find(Member.class, 2L);
findMember.setId(24L);
tx.commit();
Member member = em.find(Member.class, 1L);
em.remove(member) // 삭제
1. flush 메소드를 통한 직접 호출
tx.begin();
Member member = new Member(200L, "A");
em.persist(member);
em.flush(); // 강제 호출
System.out.println("Commit 전에 Query가 DB로 날아감");
tx.commit();
15:09:31.976 [main] DEBUG org.hibernate.SQL -
/* insert com.example.jpalearning.Member
*/ insert
into
Member
(USERNAME, MEMBER_ID)
values
(?, ?)
Hibernate:
/* insert com.example.jpalearning.Member
*/ insert
into
Member
(USERNAME, MEMBER_ID)
values
(?, ?)
DB INSERT Query 가 즉시 나감. -- flush() 호출 후 -- Transaction commit 됨.
15:09:31.981 [main] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl - committing
15:09:31.981 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Processing flush-time cascades
15:09:31.981 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Dirty checking collections
.
.
.
2. 트랜잭션 커밋 시 플러시 자동 호출.
3. JPQL 쿼리 실행 시 플러시 자동 호출
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
// 중간에 JPQL 실행
query = entityManager.createQuery("select m from Member m", Member.class);
List<Member> members = query.getResultList();
Q. 영속성 컨텍스트에 저장한 뒤 find 함수를 통해 조회를 시도하면 조회가 될까?
A. 조회가 되지 않음. flush가 실행되지 않은 상태라 Insert 문이 쓰기 지연 SQL 저장소에만 있는 상태일 것이다.
그래서 JPA의 디폴트로 JPQL 쿼리 실행 시 flush를 자동으로 날리게 되고 Insert가 된 뒤에 select절이 실행이 된다.
강의 : 자바 ORM 표준 JPA 프로그래밍