영속성 관리 - 병합

김득회·2022년 6월 8일
0

JPA

목록 보기
8/11

준영속 병합

병합은 준영속 상태나, 비영속 상태를 영속 상태로 변경하기 위해 사용하는 메서드이다.
merge() 메서드를 사용하며, 준영속 상태일 경우 해당 엔티티의 정보를 사용하여 새로운 영속 상태의
엔티티를 반환받아 사용한다.

public<T> T merge(T entity);

Member mergeMember = em.merge(member);
public class JpaContextManagement {
    static EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
    public static void main(String[] args) {
        Member member = createMember("memberA", "호두득", 20);
        member.setUsername("홍길동"); //준영속 상태에서 값 변경
        mergeMember(member);
    }

    static Member createMember(String id, String userName, int age) {
        EntityManager em1 = emf.createEntityManager();
        EntityTransaction tx1 = em1.getTransaction();
        Member member = new Member();
        try{
            tx1.begin();

            member.setId(id);
            member.setUsername(userName);
            member.setAge(age);

            em1.persist(member);
            tx1.commit();

            em1.close(); //영속성 컨텍스트1 종료 -> member 준영속 상태로 전환
        }catch (Exception e){
            e.printStackTrace();
        }
        return member;
    }

    static void mergeMember(Member member){
        //영속성 컨텍스트 2 시작
        EntityManager em2 = emf.createEntityManager();
        EntityTransaction tx2 = em2.getTransaction();
        try{
            tx2.begin();
            Member mergeMember = em2.merge(member);
            tx2.commit();

            //준영속 상태
            System.out.println("member = " + member.getUsername());

            //영속 상태
            System.out.println("mergeMember = " + mergeMember.getUsername());

            System.out.println("em2 contains member = " + em2.contains(member));
            System.out.println("em2 contains mergeMember = "+ em2.contains(mergeMember));

            em2.close(); //영속성 컨텍스트 종료
        }catch (Exception e) {
            e.printStackTrace();
        }
   }
}

merge로 병합된 엔티티는 다시 1차 캐시에 들어가 영속성 관리를 받게 된다.

영속성 컨텍스트가 관리하는 엔티티인지 확인하는 방법은 em.contains(엔티티)로 검색하면 찾을 수 있다.

병합을 통해 만들어진 엔티티는 기존에 있던 준영속상태의 엔티티와 다른 객체라는 것을 확인 할 수 있다.

코드확인

위의 코드에서 생성한 mergeMember를 생성하여 엔티티를 하나 더 만드는 것 보다는
준영속에서 병합 과정을 거쳐 영속 엔티티로 변경된 엔티티를 다시 참조하는 것이 안전하다.

//Member mergeMember = em2.merge(member);
member = em2.merge(member);

병합 과정

병합을 하는 과정은 파라메터로 넘어온 엔티티의 식별자 값을 통해 영속성 컨텍스트에서 조회하고, 찾지 못하였을 경우 DB에 접속하여 조회를 한다. => 이때 DB에서도 엔티티를 찾지 못하면 새로운 엔티티를 생성하여 병합을 진행한다.

비영속 병합

준영속 엔티티 뿐만 아니라 비영속 엔티티도 영속성 컨텍스트가 관리하는 영속 엔티티로 변환이 가능하다.
새로운 객체를 생성하여 merge() 메서드를 사용해 병합해주면 된다.

Member member = new Member();
Member newMember = em.merge(member);
tx.commit();
profile
감성 프로그래머 HoduDeuk

0개의 댓글