참조: http://www.javadev.org/files/Hibernate%20Performance%20Tuning.pdf

하이버네이트에서 패칭 전략은 애플리케이션에서 어떤 객체와 연관된 객체를 가져오는 방법이다. 즉 A->B 또는 A->Collection 이런 관계가 있을 때 A와 연관되어 있는 B 또는 Collection를 가져오는 방법이다. 쉽게 생각해보면 A를 가져갈때 B나 C도 같이 가져가는 방법이 있고, A를 가져갈땐 A만 가져가고 B는 나중에 a.b라고 접근하는 순간에 가져갈 수 있겠다. 그런데 이렇게 단순하지 많은 않다.

  • Join fetching: 연관된 인스턴스나 콜렉션을 동일한 SELECT 절에서 OUTER JOIN으로 가져온다.
  • Select fetching: 연관된 인스턴스나 콜렉션을 부가적인 SELECT 절을 사용해서 가져오기. lazy="false"라고 명시하지 않는한 이 부가적인 쿼리는 실제 해당 컬렉션에 접근할 때 발생한다.
  • Subselect fetching: 이전 쿼리나 패치에서 가져온 모든 엔티티에 연관된 인스턴스나 콜렉션을 부가적인 SELECT 절을 사용해서 가져오기. lazy="false"라고 명시하지 않는한 이 부가적인 쿼리는 실제 해당 컬렉션에 접근할 때 발생한다.
  • Batch fetching: select fetching의 최적화 전략. 하이버네이트는 인스턴스나 컬렉션을 주키나 외래키 목록을 사용해 하나의 SELECT 절로 묶어서 가져온다.

패칭 전략을 이렇게 나누기도 한다.

  • Immediate fetching: owner 쪽을 로딩할 때 컬렉션이나 속성을 그 즉시 가져온다.
  • Lazy collection fetching: 해당 컬렉션에 접근할 때 가져온다.(이게 컬렉션의 기본 전략)
  • "Extra-lazy" collection fetching: 컬렉션의 개별 요소에 접근할 때 데이터베이스에 접근한다. 컬렉션을 전부다 메모리로 가져오지 않는 방법인데 컬렉션이 매우 클때 적합하다.
  • Proxy fetching: 단일 값 관계에 있는 인스턴스는 id가 아닌 다른 속성에 접근할 때 가져온다.
  • "No-proxy" fetching: 인스턴스 변수에 접근하면 바로 가져온다. Proxy fetching에 비해 덜 lazy한 방식이지만 프록시를 사용하지 않으니 더 깔끔하다. 이 방법을 사용하려면 빌드시 바이트코드 조작을 해야 하다. 이 방법은 거의 사용하지 않는다.
  • Lazy attribute fetching: 어떤 속성이나 단일 값 관계에 접근할 때 인스턴스 변수를 접근한다. 이 방법도 빌드시 바이트코드 조작을 해야 하며 거의 사용하지 않는다.