해결된 질문
작성
·
553
0
일전에, 지연로딩
을 사용하면 객체의 참조를 얻을 때가 아닌, 실제 필드(메서드 포함) 에 접근할 때 프록시 객체가 진짜 객체로 초기화 되는 것으로 이해했습니다.
그런데 아래와 같이 코드를 짜고 실행해보니, 객체의 참조를 얻을 때 쿼리가 나가는 것 처럼 보이더라고요.
// 팀
Team teamA = new Team();
teamA.setName("팀A");
em.persist(teamA);
Team teamB = new Team();
teamB.setName("팀B");
em.persist(teamB);
// 회원: member1, 2 는 팀A 소속. member3은 팀B 소속
Member member1 = new Member();
member1.setUsername("회원1");
member1.setTeam(teamA);
em.persist(member1);
Member member2 = new Member();
member2.setUsername("회원2");
member2.setTeam(teamA);
em.persist(member2);
Member member3 = new Member();
member3.setUsername("회원3");
member3.setTeam(teamB);
em.persist(member3);
em.flush();
em.clear();
// Query
String query = "select m from Member m";
List<Member> findMembers = em.createQuery(query, Member.class)
.getResultList();
for (Member member : findMembers) {
System.out.println("member = " + member.getUsername() + ", " + member.getTeam());
}
tx.commit();
(나간 쿼리)
Hibernate:
/* select
m
from
Member m */ select
member0_.MEMBER_ID as MEMBER_I1_7_,
member0_.createdBy as createdB2_7_,
member0_.createdDate as createdD3_7_,
member0_.lastModifiedBy as lastModi4_7_,
member0_.lastModifiedDate as lastModi5_7_,
member0_.COMPANY_CITY as COMPANY_6_7_,
member0_.COMPANY_STREET as COMPANY_7_7_,
member0_.COMPANY_ZIPCODE as COMPANY_8_7_,
member0_.city as city9_7_,
member0_.street as street10_7_,
member0_.zipcode as zipcode11_7_,
member0_.LOCKER_ID as LOCKER_15_7_,
member0_.TEAM_ID as TEAM_ID16_7_,
member0_.USERNAME as USERNAM12_7_,
member0_.endDate as endDate13_7_,
member0_.startDate as startDa14_7_
from
Member member0_
Hibernate:
select
team0_.TEAM_ID as TEAM_ID1_10_0_,
team0_.createdBy as createdB2_10_0_,
team0_.createdDate as createdD3_10_0_,
team0_.lastModifiedBy as lastModi4_10_0_,
team0_.lastModifiedDate as lastModi5_10_0_,
team0_.name as name6_10_0_
from
Team team0_
where
team0_.TEAM_ID=?
member = 회원1, hellojpa.domain.Team@26ae880a
member = 회원2, hellojpa.domain.Team@26ae880a
Hibernate:
select
team0_.TEAM_ID as TEAM_ID1_10_0_,
team0_.createdBy as createdB2_10_0_,
team0_.createdDate as createdD3_10_0_,
team0_.lastModifiedBy as lastModi4_10_0_,
team0_.lastModifiedDate as lastModi5_10_0_,
team0_.name as name6_10_0_
from
Team team0_
where
team0_.TEAM_ID=?
member = 회원3, hellojpa.domain.Team@6bd16207
저는 위 코드 중 System.out.println 과정 중 프록시 객체가 초기화가 되어서 위같은 쿼리가 나왔다고 생각하는데 제 판단의 근거가 맞는지 궁금합니다.System.out.println("member = " + member.getUsername() + ", " + member.getTeam());
System.out.println 을 사용하면 자동으로
객체.toString()
이 호출되고, 따라서 필드(메서드)에 접근 했으므로 이 시점에 프록시 객체가 엔티티로 초기화 되었다.
위 처럼 이해하는게 맞을까요? 항상 애써주시는 영한님과 서포터님들께 감사드립니다!!
답변 1
1
안녕하세요. manhae님
프록시의 메서드에 접근하면 초기화가 진행됩니다. toString()의 경우도 포함됩니다.
@Id를 조회하는 getId()의 경우는 내부에서 이미 id 값을 가지고 있기 때문에 초기화 되지 않습니다.
감사합니다.