강의

멘토링

커뮤니티

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

Luke님의 프로필 이미지
Luke

작성한 질문수

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

@DATA 롬복 어노테이션과 LAZY로딩과의 관계

작성

·

229

0

 안녕하세요. 강사님,

LAZY로딩과 관련해서 성능최적화 공부중에 있는데요,

작업중 특이한 경우를 보게되서 질문을 드립니다.

어떠한 User라는 Entity가 있고,

해당 entity에는 다른 테이블들과 @ManyToOne, @oneToMany 관계를 가지고 있습니다.

당연히 로딩은 Fetch.LAZY로 설정해 두었구요.

이 상태에서 해당 entity를 조회하는 userRepository.findById() 의  코드를 실행시켰을때,
user를 제외한 나머지에대해서도 조회쿼리가 발생하는 문제가 발생했습니다.

(user 조회후 , A,B,C,D에 대해서 추가 쿼리가 발생)

이것저것 수정하다가 @Data를 @Getter@Setter로 변경후에 정상적으로 동작하는것을 확인했습니다.

(user만 조회)

혹시 @Data어노테이션이 LAZY로딩에 영향을 주는게 있는지 궁금합니다.
구글에서 검색해봣지만 만족스러운 내용을 찾지 못해서 질문드립니다.

해당 entity는 대략적으로 아래와 같습니다.

@Entity
@Getter
@Setter
@Table(name = "user")
public class User{

   ////  기타 컬럼 field

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "a_id")
    private A a;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "b_id")
    private B b;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "c_id")
    private C c;

    @OneToMany(mappedBy = "ds", fetch = FetchType.LAZY)
    private List<D> ds;

}

답변 1

1

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

안녕하세요. Luke님

@Data에 있는 toString을 자동으로 만들어주는 기능 때문입니다. 기본적으로 모든 필드를 다 호출해서 toString을 만들도록 되어 있습니다.

따라서 System.out.println(user)를 하게되면 user.toString이 호출되는데, 모든 데이터를 다 건들어서 지연로딩이 호출되어 버립니다.

감사합니다.

Luke님의 프로필 이미지
Luke
질문자

안녕하세요 강사님

@Data의 toString은 컴파일 되는 시점에서 생성되는게 아닌가요??

그렇다면 system.out.println을 사용하지 않아도, id로 조회하는 시점에

toString이 호출되면서 위에서 말한  문제가 발생하는거라 이해하면 될까요?

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

@Data는 컴파일 시점에 toString을 생성합니다. -> 네 맞습니다.

id로 조회하는 시점에는 toString을 호출하지는 않습니다.

코드 어디에선가 toString을 호출했을 것 같다고 추정됩니다.(주로 println으로 객체를 직접 출력하는 경우)

디버그 모드 또는, System.out.println("...")으로 로그를 하나씩 남기면서 정확히 어디에서 지연로딩의 초기화가 일어나는지 확인해보시면 더 쉽게 찾으실 수 있을거에요.

감사합니다.

Luke님의 프로필 이미지
Luke

작성한 질문수

질문하기