'Fetch'에 해당되는 글 2건

  1. 2008.04.13 HQL - fetch
  2. 2008.04.09 늦은로딩과 조회방식

HQL - fetch

Hibernate 2008.04.13 02:08
hql에서 연관 객체를 조회하는 방식을 결정할 수 있습니다.
객체를 조회하는 방식에 대해서는 이전에 다뤘던 늦은로딩과 조회방식을 참고하는걸 추천 합니다.
hql에서는 join fetch, left join fetch 키워드를 사용하여 조회 방식을 결정 합니다. fetch 키워드를 사용한다는 의미는 늦은로딩을 하지 않고 내부조인 또는 외부조인으로 연관 객체를 한번에 로딩하겠다는 의미 입니다.

다음 hql은 내부조인으로 모든 객체를 한번에 가져 옵니다.
from Seller s join fetch s.items

외부 조인을 사용할 수도 있습니다.
from Seller s left join fetch s.items

lazy 속성이 false일 때 다음 두 hql은 동일한 SQL을 실행 합니다.
from Seller s join fetch s.items
from Seller s join s.items
하지만 fetch 키워드를 사용하면 연관 객체가 결과 리스트에 포함되지 않습니다.
즉 결과 리스트에 Seller 객체만 담겨 있습니다.

1-n 관계에서는 부모객체가 중복되서 나타나므로 select 절에서 중복을 제거해야 합니다.
select s distinct from Seller s join fetch s.items
수행되는 SQL에 distinct 키워드가 포함되지만 의미는 없습니다. 부모 객체의 중복 제거 작업은 메모리상에서 이루어 집니다. 하지만 조회되는 행들 자체가 중복이 아니기에 큰 문제는 없습니다.

래퍼런스에는 불가능하다고 나와 있지만 페이징도 가능 합니다.
session.createQuery("from Seller s join fetch s.items")
    .setFirstResult(5)
    .setMaxResults(20);
fetch 키워드를 사용하든 안하든 일단 조인이기 때문에 Seller 객체는 중복되서 나타날 것 입니다.
그래서 fetch 키워드를 사용하지 않을때는 select 절에서 Seller 객체만 조회한후 distinct 키워드를 이용해 중복을 제거한 뒤 페이징을 했었습니다. 하지만 fetch 키워드를 사용하면 상황이 다릅니다. fetch 라는 특성상 연관객체는 무조건 결과 행에 포함되기 때문에 Seller 객체의 중복을 결과 행에서 제거할 수가 없습니다. 하이버네이트는 fetch 사용시 페이징을 사용하면 일단 메모리상에서 Seller 객체의 중복을 제거한 뒤 메모리상에서 페이징을 합니다. 데이터가 많을 때는 사용을 자체해야 합니다.

1-1 관계나 n-1 관계에서는 실행되는 SQL에서 페이징을 하며 결과는 정상적 입니다.
기준이 Item 객체이기 때문에 결과 행에서 Item 객체의 중복은 없습니다.
session.createQuery("from Item i join fetch i.seller s where s.id = 5")
    .setFirstResult(0)
    .setMaxResults(10);

fetch 키워드 사용시 with 조건은 사용할 수 없습니다.
사용하면 예외가 발생하며 이런 메세지가 등장 합니다.
with-clause not allowed on fetched associations; use filters
필터를 사용하라네요...


주의사항
래퍼런스에 fetch 키워드 사용시 아래의 오퍼레이션은 사용할 수 없다고 나와 있습니다.
몇몇은 이미 위에서 언급된 내용들 입니다.
  • iterate() 사용 불가
  • 페이징은 결과가 기대하는대로 나오지 않음
  • with 조건 사용 불가
  • bag 매핑들에 대해 예기치 않은 결과가 발생
  • full join fetch와 right join fetch는 의미가 없음

신고

'Hibernate' 카테고리의 다른 글

HQL - 집계 함수, group by, having  (0) 2008.04.16
HQL - 컬렉션 필터  (0) 2008.04.13
HQL - fetch  (0) 2008.04.13
HQL - select 절  (0) 2008.04.13
HQL - join  (0) 2008.04.13
HQL - where 절  (0) 2008.04.13
Posted by 째코
lazy
  • 하이버네이트는 디폴트로 lazy 로딩
  • lazy 로딩이 안되는 경우
-주키를 공유하는 1-1 연관
-컴포넌트 타입의 1-1 연관
  • Session이 닫힌 후 lazy 로딩을 시도하면 LazyInitializationException 발생
  • 컬렉션 디폴트 lazy(fetch=select) 로딩은 "n+1 select" 문제에 매우 취약
  • fetch 속성 값을 join 으로 변경하면 외부조인이 실행됨으로써 해결

fetch
  • fetch는 연관 객체를 검색하는 방법
  • fetch 속성이 영향을 미치는 범위
- get(), load() 를 통한 로딩
- 연관이 네비게이트 될 경우
- Criteria 질의
- HQL 질의(값이 select, subselect 일 경우만 영향을 미치고 join은 영향 없음)

fetch 속성의 값들
join : 외부 조인을 사용하여 연관된 객체를 검색 (lazy 속성이 true라도 외부조인으로 한방에 검색)
select(디폴트 값) : 명시적으로 lazy 로딩을 불가능하게 하지 않는 이상 연관 객체에 엑세스 하는 순간 검색
subselect : 위 select와 동일하지만 연관 객체 검색시 서브쿼리를 이용

subselect의 문제점
부모 객체 100개가 있고 각 부모마다 자식 객체를 20개씩 가지고 있을 경우
부모 객체 100개를 리스트로 가져와서 그 중 임의의 부모객체를 통해 자식 객체를 엑세스 할 때
모든 자식 객체 2000개를 한번에 로딩함
단, 부모 객체를 리스트로 가져오지 않고 특정 식별 값으로 하나만 가져올 경우 select 와 동일함
신고

'Hibernate' 카테고리의 다른 글

HQL - 시작, from 절  (0) 2008.04.13
HQL - API  (0) 2008.04.13
늦은로딩과 조회방식  (0) 2008.04.09
동시 접근 제어  (0) 2008.03.29
openSession()과 currentSession()의 close()  (0) 2008.03.04
Session으로 작업하기  (0) 2008.03.02
Posted by 째코


티스토리 툴바