영속성 컨텍스트
- 엔티티를 영구적으로 저장하는 환경
- 앱과 DB사이의 객체를 보관하는 가상의 DB역할
- **엔티티 메니저**를 통해 저장하거나 조회한다.
구분 | persist() |
merge() |
---|---|---|
용도 | 새로운 엔티티를 영속성 컨텍스트에 저장 | 영속 상태의 엔티티 반환(영속상태와 무관) |
상태 | 비영속 상태 → 영속 상태 | 식별자(id)로 찾을 수 있으면 병합하여 조회, 없으면 새로 생성하여 병합 |
반환 값 | void | 영속 상태의 새로운 엔티티 |
중복 처리 | 중복 ID가 있으면 예외 발생 | 중복 ID가 있으면 UPDATE 처리 |
영속성 컨텍스트 | 새로운 엔티티로 등록 | 이미 존재하는 엔티티를 병합 |
save()
함수는 내부적으로 isNew(Entity)
연산을 수행하여,
해당 엔티티가 신규로 등록되는 엔티티이면 persist()
를, 기존에 존재하는 엔티티면 merge()
를 수행한다.
+JPA의 FlushMode.AUTO(기본)에서는 “현재 컨텍스트에 반영된 변경 사항을쿼리 실행 전에 DB에 동기화(flush) 한다.
1 - HfMarketingCode A = new HfMarketingCode();
2 - A.setHitCode("testCode1");
3 - A.setCodeName("testName2");
4 - hfMarketingCodeRepository.save(A);
5 - HfMarketingCode B = hfMarketingCodeRepository.findAllByHitCode("testCode1");
testCode1
을 id로 갖는 testName1
의 값을 testName2
로 바꿀때, 4번이 아닌, 5번 시점에 update가 발생한다.// 객체를 생성한 상태 (비영속)
Member member = new Member();
// 객체의 값 변경해도 영속상태에 영행 X
member.setName("이태성");
// 객체를 생성한 상태(비영속)
Member member = new Member();
member.setName("이태성");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
//엔티티 매니저를 사용하여 영속상태로 등록
em.persist(member);
// 엔티티 매니저를 사용하여 영속상태를 분리 -> 준영속 상태
em.detach(member);
// 엔티티 매니저를 사용하여 영속상태를 상태 -> 삭제 상태
em.remove(member);
// 영속성 컨텍스트를 비워도 관리되던 엔티티는 준영속성 상태가 된다.
em.clear();
// 영속성 컨텍스트를 종료해도 관리되던 엔티티는 준영속 상태가 된다.
em.close();
Member a = em.find(Member.class, "A");
Member b = em.find(Member.class, "A");
System.out.println(a==b) // true
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // 트렌젝션 시작
em.persist(memberA);
em.persist(memberB);
// 커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // 트렌젝션 커밋
영속성 컨텍스트에서 관리하는 객체는 수정되어도 DB에 바로 Insert 쿼리를 날리지 않는다. SQL 쿼리들을 모아놓았다가 flush(커밋) 될 때 모아둔 쿼리를 모두 날린다.
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
// 영속 엔티티 조회
Member member = em.find(Member.class, "A");
// 영속 엔티티 데이터 수정
member.setName("이태성");
member.setJob("프로그래머");
transaction.commit(); // [트랜잭션] 커밋
find()
후 해당 객체의 값을 수정 후 커밋하면 어떻게 될까?플러시의 흐름
em.flush()