• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

toString() 만 사용해도 프록시객체가 초기화되는 것이 맞나요?

23.03.19 19:20 작성 조회수 464

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 값을 가지고 있기 때문에 초기화 되지 않습니다.

감사합니다.