해결된 질문
작성
·
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이 실행됩니다.
감사합니다.
안녕하세요. 감바스님
findTeam.getMembers()와 같이 단순히 컬렉션을 조회만 하는 경우에는 초기화 일어나지 않습니다.
컬렉션 안에 있는 값을 실제 사용할 때 초기화가 일어납니다.
참고로 컬렉션의 .size() 같은 메서드를 호출해도 초기화가 일어납니다.
감사합니다.
안녕하세요 영한님!
첫번째 select문은 em.find(Team.class, team.getTeamId())를 호출 했기에 출력이 됐다고 이해했습니다.
궁금한 점은 두 번째 select문 같은 경우에는 지연 로딩 때문에 findTeam.getMembers(); 할 경우 출력이 되겠지 하고 예상 했습니다. 그래서 코드를 실행하고 콘솔을 보니 =============== 가 찍히고 나서 두 번째 select문이 찍혀 있었습니다. 그래서 왜 =============== 보다 두번째 select문이 나중에 찍히는지 궁금합니다.
그리고 두번째 select 문이 findTeam.getMembers(); 땜에 출력이 되는건지 궁금합니다.