legacy/JPA

[JPA] 준영속 상태 엔티티 -> 영속 상태 엔티티로 만들기, merge() (old2)

heemang.dev 2023. 9. 24. 15:11

 

1. 비영속 상태의 엔티티 생성

영속성 컨텍스트(PersistContext)에 한 번도 저장된 적이 없는 Member를 생성합니다. EntityManager를 통해 persist를 하지 않았기 때문에 비영속 상태입니다.

void test() {
    // member1 생성
    Member member1 = new Member();
    member1.setName("member1");
}

2. 비영속 상태 -> 영속 상태

EntityManager를 통해 Member를 persist하였습니다. 따라서 영속성 컨텍스트에 의해 관리되는 영속 상태의 엔티티가 됩니다.

(DB에서 조회되지 않는다.)

void test() {
    // member1 생성
    Member member1 = new Member();
    member1.setName("member1");

    // member1 -> 영속성 컨텍스트에 저장, member1은 영속 상태
    em.persist(member1);
}

3. 영속성 컨텍스트 초기화, 영속 엔티티 -> 준영속 엔티티

flush()는 쓰기 지연 저장소에 저장된 쿼리문을 DB에 전송합니다. flush() 시점에 Member가 DB에 저장됩니다.

clear()는 영속성 컨텍스트에 저장된 영속 상태의 엔티티를 모두 초기화합니다. 따라서 영속성 컨텍스트로부터 관리되는 엔티티가 존재하지 않게 됩니다. 이 시점에 영속 엔티티에서 준영속 엔티티로 바뀝니다.

void test() {
    // member1 생성
    Member member1 = new Member();
    member1.setName("member1");

    // member1 -> 영속성 컨텍스트에 저장, member1은 영속 상태
    em.persist(member1);

    // DB에 member1을 저장하는 Insert 쿼리 날림
    em.flush();
    // 영속성 컨텍스트 초기화 -> member1은 비영속 상태
    em.clear();
    // 영속성 컨텍스트 종료
    em.close();
}

4. 준영속 엔티티 -> 영속 엔티티

merge()를 통해 준영속 상태였던 member1을 영속 상태로 바꿉니다.

void test() {
    // member1 생성
    Member member1 = new Member();
    member1.setName("member1");

    // member1 -> 영속성 컨텍스트에 저장, member1은 영속 상태
    em.persist(member1);

    // DB에 member1을 저장하는 Insert 쿼리 날림
    em.flush();
    // 영속성 컨텍스트 초기화 -> member1은 비영속 상태
    em.clear();
    // 영속성 컨텍스트 종료
    em.close();

    // 병합, 준영속 엔티티 -> 영속 엔티티
    Member mergeMember = em.merge(member1);
}

여기서 주의할 점은 member는 여전히 준영속 상태라는 것입니다. merge() 메서드는 준영속 상태의 엔티티를 받아서 새로운 영속 상태의 엔티티를 반환합니다.

contains() 메서드의 경우 넘겨 받은 엔티티가 영속성 컨텍스트에 의해 관리되는 영속 엔티티인지 true/false를 반환합니다. member는 준영속 상태, mergeMember는 영속 상태이기 때문에 false와 true를 순서대로 반환합니다.

boolean member1ContainsPersistContext = em.contains(member1); // false
boolean mergeMemberContainsPersistContext = em.contains(mergeMember); // true

System.out.println("member1이 영속 상태인가? -> " + member1ContainsPersistContext);
System.out.println("mergeMember는 영속 상태인가? -> " + mergeMemberContainsPersistContext);

준영속 상태인 member1의 이름을 변경하여도 DB에 반영되지 않습니다. 영속성 컨텍스트에 의해 관리되지 않기 때문에 식별자 값으로 변경을 추적하지 않기 때문입니다.

자바 ORM 표준 JPA 프로그래밍


결론

merge()는 준영속 상태의 엔티티를 영속 상태의 엔티티로 만들어줍니다. 주의해야할 점은 기존의 준영속 상태의 엔티티를 영속 상태로 바꾸는 것이 아닌, 새로운 영속 상태의 엔티티를 만들어준다는 것입니다. 


새로운 게시물1

새로운 게시물2(최신)