티스토리 뷰

반응형

지연 로딩?

예를 들어 A라는 객체가 B라는 객체를 가지고 있다면, A를 데이터를 불러 올 때 해당되는 B의 데이터도 필요합니다. 하지만 B객체에 대한 정보가 굳이 필요 없는 상황에서도 B데이터까지 모두 데이터베이스에서 불러오는 작업을 한다면 비효율적인 작업이 됩니다. 이런 상황에서 성능을 올리기 위한 방법으로 JPA의 '지연 로딩'이 있습니다. 실제로 B객체의 데이터가 사용 될 때, B데이터를 불러오고, 그렇지 않다면 굳이 B객체 데이터를 사용하지 않습니다. 지연 로딩을 구현하기 위해서 JPA (정확히는 Hibernate)에서는 프록시 디자인 패턴을 사용합니다.

프록시 디자인 패턴


이미지 출처 ㅣ 위키 백과


클라이언트(Client)가 특정 객체(Subject)를 사용하게 될 때, 이를 구현한 (혹은 상속받은) 프록시(대행자) 객체를 만들어서 마치 클라이언트(Client) 입장에서 실제 객체를 사용하는 것처럼 느껴지게 하는 디자인 패턴이 프록시 디자인 패턴입니다. 개발자 입장에서는 실제 클래스(RealSubject)를 구현하기만 한다면, 부가적인 기능은 Proxy에서 추가됩니다. 

프록시 객체를 이용한 지연 로딩의 원리

JPA (Hibernate)에서 지연 로딩을 구현하기 위해서 프록시 객체를 어떤식으로 사용하는지 알아봅시다. 예제로 사용되는 코드는 아래와 같습니다. 댓글(Comment)와 게시글(Article)의 관계를 간략하게 표시했습니다. 댓글은 게시글을 가지고 있는 관계에 있습니다.

@Entity @Setter @Getter
public class Comment { //댓글
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "article_id")
    private Article article; //Comment는 Article을 가지고 있다.

    . . .
}

@Entity @Setter @Getter
public class Article { //게시글
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    . . .
}

만약 댓글 객체 comment가 존재한다면, comment.getArticle()을 하는 방법으로 해당 댓글과 연관된 게시글을 조회 할 수 있습니다. 하지만 일반적으로 게시글은 많은 정보를 담고 있는 무거운 엔티티입니다. 굳이 게시글의 정보가 필요 없는 상황에서도 데이터베이스에서 게시글의 대한 정보를 가져온다면, 성능이 많이 떨어지게 됩니다. JPA (Hibernate)에서 지연 로딩을 사용한다면 실제로 게시글에 정보가 필요한 순간! 코드로 말하자면 comment.getArticle()을 하는 순간 데이터베이스에서 게시글 정보를 조회하게 됩니다.


하지만, 개발자가 만든 Article(게시글) 클래스는 지연 로딩을 하기 위한 기능이 없는데, 어떻게 이런 기능을 수행 할 수 있을까요? 바로 JPA (Hibernate)가 내부적으로 개발자가 만든 Ariticle의 프록시 객체를 생성합니다. 그리고 이 프록시 게시글 객체는 댓글에게 마치 자신이 진짜 게시글 객체인양 행동합니다. 그리고 이 프록시 객체는 게시글 데이터가 필요한 시점에 데이터베이스에서 게시글 정보를 가져오는 기능(초기화 기능)을 가지고 있습니다. 이것이 JPA(Hibernate)가 지연 로딩을 프록시로 구현한 원리입니다.

반응형
댓글
댓글쓰기 폼