문제

나는 다양한 집합 뿌리를 가진 풍부한 객체 모델을 가진 프로젝트를 진행하고 있습니다.

우리는 사용하고 있습니다 스택 (activerecord와 함께 nhibernate 로의 모노레일).

우리는 집계 뿌리를 게으른 것으로 표시했습니다 [ActiveRecord(Lazy = true)] 객체 그래프를 열망하기 위해 저장소에서 '열심히'루틴을 맞춤화했습니다. 우리는 HQL을 사용하여 뿌리의 자녀 컬렉션에서 열심 인 페치를 정의합니다.

예를 들어 Account 집계 뿌리 (그리고 게으른로드) 우리는 열심히 가져올 것입니다. Account .. Order .. Product 완전한 그래프를위한 엔티티.

그래서 지금까지 (희망적으로) 놀라운 일이 아닙니다.

이제 위의 예에서 제품도 표시됩니다. [ActiveRecord(Lazy = true)], 이것은 HQL의 열렬한 페치 지침을 막는 것 같습니다.

게으른로드 아동 물체의 열렬한 페치를 강요하는 방법을 아는 사람이 있습니까? ??

이안을 건배합니다

업데이트:

OK 여기에 'Me.yahoo.com/../1'의 예제를 사용하여 HQL이 예제를 사용하여 Imuleiquery를 사용하여 다수의 관계를 가져올 때 N+1 종속성을 재개합니다. 우리는 또한 다수의 매핑 클래스를 명시 적으로 사용하고 있습니다. 결과적으로 우리의 HQL은 다음과 같습니다.

from Account a 'm eager loading the graph
inner join fetch a.AccountsOrders ao 
inner join fetch ao.Order
from Account a 'm eager loading the graph
inner join fetch a.AccountAddresses aa
inner join fetch aa.Address ad
where a.ID = ?

... 따라서 2 SQL 문을 실행하고 필요한 최소 행 세트를 반환하며이를 단일 객체 그래프로 해결할 수 있습니다. 멋진.

하지만 ... 만약 그렇다면 Address 게으른로드 (및 Order 그렇지 않았습니다), 접근 Order 추가 SQL 문을 트리거하지는 않지만 액세스 할 수 있습니다 Address 사실에도 불구하고 둘 다 열망했다.

그래서 왜 게으른 짐을지는 실체는 그렇지 않습니다 Address, 위의, 열망은 위의 진술에 의해 가져 왔습니까?

도움이 되었습니까?

해결책

왜 열망하는 행동을 원하십니까?

ActiveRecord의 모든 관계 속성에는 'Lazy ='매개 변수가 있습니다. 소속을 제외하고는 모두. SONGSTO는 종속 객체가 activereCord 속성에서 Lazy = true인지 확인한 다음 선택 또는 조인을 수행하는 대신 개체에 대한 프록시를 만듭니다.

게으른로드가 작동하려면 클래스 인스턴스의 모든 방법과 속성을 가상으로 표시해야합니다. 이를 통해 ActiveRecord는 동적 프록시 클래스를 구성 할 수 있습니다.

이제 성능을 위해 완전한 그래프를 가져 오는 것이 좋은 생각처럼 들릴지 모르지만 실제로는 느리게 가능합니다. 이유는 다음과 같은 3 가지가 있습니다.

1.) SOLFINGSTO에는 관련 객체를 당기는 방법을 정의하기위한 Fetch 옵션이 있습니다. Fetchenum.join forces ar. Fetchenum. SELECT FERCES AR은 각 객체에 대해 별도의 선택 문을 사용할 수 있습니다. 조인은 느리게 진행되며, 전환에서 개별 선택으로 10 배의 성능이 향상됩니다. Lazy = true + fetchenum.select 및 eager 사이의 클라이언트 코드에는 효과적인 차이가 없습니다.

2.) nhibernate는 캐싱을합니다. 객체가 이미 세션이나 레벨 2 캐시에 캐시 된 경우 양식을로드하여 추가 작업을 피할 수 있습니다.

3.) 객체 그래프의 일부를 참조하지 않은 경우 게으른 하중의 이점을 놓칠 것입니다. 다시 한번 당신은 필요보다 더 많은 일을 할 것입니다.

다른 팁

계정에서 "내부 조인 페치"를 수행하십시오. 따라서 이와 같은 대신 (아마도 이미 가지고있는 것) :

"from Account a inner join fetch a.Order where a.ID = ?"

Order.Product도 가져 오라고 말하십시오.

"from Account a inner join fetch a.Order inner join fetch a.Order.Product where a.ID = ?"

"Nhibernate in Action"에서 225 페이지 :

Nhibernate는 현재 하나의 컬렉션을 간절히 가져 오는 것으로 제한합니다.

주소를 가져 오기위한 두 번째 쿼리를 설명 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top