인프런 커뮤니티 질문&답변

감바스님의 프로필 이미지
감바스

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

양방향 연관관계와 연관관계의 주인 2 - 주의점, 정리

쿼리를 보내는 부분은 따로 스레드를 만들어서 처리하는건지 궁금합니다.

해결된 질문

작성

·

87

0

public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            Team team = new Team();
            team.setName("TeamA");
            em.persist(team);

            Member member = new Member();
            member.setName("member1");
            member.setTeam(team);
            em.persist(member);

//            team.getMembers().add(member);

            em.flush();
            em.clear();

            Team findTeam = em.find(Team.class, team.getTeamId());
            List<Member> members = findTeam.getMembers();
            System.out.println("===============");
            for (Member m : members) {
                System.out.println("===========");
                System.out.println("m = " + m.getName());
                System.out.println("===========");
            }


            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }

        emf.close();
    }
}

위 코드를 실행했을때 출력 결과는 아래와 같습니다.

Hibernate: 
    select
        t1_0.TEAM_ID,
        t1_0.name 
    from
        Team t1_0 
    where
        t1_0.TEAM_ID=?
===============
Hibernate: 
    select
        m1_0.TEAM_ID,
        m1_0.MEMBER_ID,
        m1_0.USERNAME 
    from
        Member m1_0 
    where
        m1_0.TEAM_ID=?
===========
m = member1
===========

 

제가 예상한 실행 결과는 findTeam.getMembers(); 로 인해 두 번째 select 쿼리문이 나오고 그 다음에 =============== 가 출력 될거라고 예상을 했습니다.

근데 실행 결과는 =============== 가 먼저 출력 되고 두 번째 select 쿼리문이 출력 됐습니다.

그래서 이걸 보고 든 생각이 main 스레드가 코드를 한줄 씩 실행하다가 findTeam.getMembers(); 부분에서 SQL문을 디비로 보낼 스레드를 만들어서 해당 스레드에게 그러한 역할을 넘기고 바로 다음줄을 실행하여 =============== 가 두번째 select 쿼리문 보다 먼저 출력되는건지 궁금합니다.

 

감사합니다.

 

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 감바스님

em.clear()를 호출했기 때문에 영속성 컨텍스트에는 엔티티가 존재하지 않습니다.

이후에 em.find(Team.class, team.getTeamId())를 호출하게 되면 DB에서 엔티티를 조회하게 됩니다.

따라서 이 시점에 SQL이 실행됩니다.

감사합니다.

감바스님의 프로필 이미지
감바스
질문자

안녕하세요 영한님!

첫번째 select문은 em.find(Team.class, team.getTeamId())를 호출 했기에 출력이 됐다고 이해했습니다.

궁금한 점은 두 번째 select문 같은 경우에는 지연 로딩 때문에 findTeam.getMembers(); 할 경우 출력이 되겠지 하고 예상 했습니다. 그래서 코드를 실행하고 콘솔을 보니 =============== 가 찍히고 나서 두 번째 select문이 찍혀 있었습니다. 그래서 왜 =============== 보다 두번째 select문이 나중에 찍히는지 궁금합니다.

그리고 두번째 select 문이 findTeam.getMembers(); 땜에 출력이 되는건지 궁금합니다.

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 감바스님

findTeam.getMembers()와 같이 단순히 컬렉션을 조회만 하는 경우에는 초기화 일어나지 않습니다.

컬렉션 안에 있는 값을 실제 사용할 때 초기화가 일어납니다.

참고로 컬렉션의 .size() 같은 메서드를 호출해도 초기화가 일어납니다.

감사합니다.

감바스님의 프로필 이미지
감바스

작성한 질문수

질문하기