2009-10-07 6 views
2

3 개의 추상화 할 수없는 클래스가 있습니다. MyClubUser 및 HisClubUser 클래스는 User 클래스에서 상속됩니다. 나는 서브 클래스 전략 당 하나의 테이블, 즉 @Inheritance(strategy = InheritanceType.JOINED)을 사용한다.최대 절전 모드 상속 전략 및 이유

필자가 관찰 한 바에 따르면 생성 된 SQL은 사용자 클래스에 대한 쿼리를 수행 할 때 외부에서 HisClubUser 및 MyClubUser를 사용합니다. Hibernate가 내 관심사가 User 일 때 [다른 테이블에 합류하는] 이유는 무엇입니까? 내 요점은 데이터가 검색되지만 사용자 인스턴스가 반환되면 MyClubUser 또는 HisClubUser에서 이러한 속성에 액세스 할 수 없습니다. 또한 왼쪽 외부 조인없이 사용자 테이블을 쿼리하는 쿼리와 비교할 때 추가 오버 헤드가 발생합니까?

덕분에 최대 절전 모드가 '다형성 질의'를 실행할 수 있도록

답변

5

최대 절전 모드 는 항상는 지속 된 개체의 실제 유형을 반환합니다. "MyClubUser"를 저장 한 경우 "MyClubUser"로 반환되며 결코 "사용자"로 반환되지 않습니다. 그 이유는 Hibernate가 "MyClubUser"를 "User"로 반환하고 다시 그것을 지속한다면 "MyClubUser"에 정의 된 모든 추가 속성을 잃게 될 것이기 때문입니다.

그렇게하기 위해, Hibernate는 실제 타입이 무엇인지를 알아야한다. InheritanceType.JOINED 전략의 경우이를 확인하는 유일한 방법은 모두 상속 계층 구조의 테이블을 확인하는 것입니다 (기술적으로 모든 테이블이 현재 레벨 또는 현재 트리 분기의 현재 레벨보다 커야합니다). 당신은 같은 계층 구조 그래서, 만약 :

  Root 
     / \ 
     Node1 Node2 
    / \ 
    Node11 Node12 

및 루트 선택하려는, Hibernate는 외부가 모든 테이블에 조인 할 것입니다. Node1에서 선택하는 경우, Hibernate는 Node1과 Root에서 내부 조인과 Node11과 Node12에서 외부 조인을 수행합니다. Node2는 Node1의 자손이 아니기 때문에 건드리지 않습니다.

외부 조인 오버 헤드가가는 한 - 분명히 오버 헤드가 있지만 가입 한 전략에 대해 지불하는 가격입니다. discriminators 이것을 피하기 위해 사용할 수 있지만 그 자체 부작용이 함께 제공됩니다. 그 오버 헤드가 중요한지 아닌지는 계층 구조, 인덱스 및 기타 여러 가지 요소의 깊이와 보급 여부에 달려 있습니다. KLE의 제안을 듣고 프로필을 작성하십시오.

+0

+1이 세부 사항에 대해 감사 드리며, 원래 SimpleUser 제안이 InheritanceType.JOINED와 함께 작동하지 않는 이유를 분명히했습니다. 나는 그 대답을 누군가의 말을 오해하지 않도록 제거했다. – KLE

2

당신은 사용자에 쿼리. MyClubUser와 HisClubUser는 본질적으로 User 객체이기 때문에 (사용자로부터 상속 받음) Hibernate는 이러한 종류의 사용자도 검색 할 것입니다.

4

최대 절전 모드가 내 관심사가 사용자 인 [다른 테이블에 가입하는] 이유는 무엇입니까?

모든 HisClubUser 또한 유효한 User 인스턴스이기 때문에 User를 요청할 때이를 검색하는 것이 좋습니다.

데이터가 검색 되더라도 내 포인트는 사용자 인스턴스가 반환되면 MyClubUser 또는 HisClubUser에서 이러한 속성에 액세스 할 수 없습니다.

정말 확실합니까? 리턴 된 유효한 클래스를 (예를 들어, 디버그에서) 점검하십시오. 서브 클래스 여야합니다. 따라서 다운 캐스팅이 가능하고 속성에 액세스 할 수 있습니다.

또한 왼쪽 외부 조인을 사용하지 않고 사용자 테이블을 쿼리하는 쿼리와 비교할 때 추가 오버 헤드가 발생합니까?

예, 추가 조인에는 오버 헤드가 있습니다. 중요 할 수도 있고 아닐 수도 있습니다. 귀하의 구체적인 경우에 테스트 해보기를 권합니다.

+1

+1. 그러나 SimpleUser 제안은 도움이되지 않을 수 있으므로 제거해야합니다. 내 대답에 "이유"를 설명했습니다. – ChssPly76

+0

@ ChssPly76 감사합니다. 나는 당신의 대답을 읽었으며, 이제 나는 왜 "왜"를 정확하게 이해합니다. 당신은 맞습니다 :-) – KLE

+0

고마워요 ... 이제 이해합니다. 내가 지금하고있는 일은 MyClubUser와 HisClubUser가 User로부터 상속받는 대신 User와 1 대 1의 관계를 가질 것입니다. MyClubUSer와 HisClubUser의 추가 속성에 액세스하려면 다시 쿼리합니다. 사용자는 로그인 용입니다. 대부분의 경우 특정 클래스가 사용됩니다. User의 속성을 읽는 경우가 있습니다. @KLE 확신합니다. 이 쿼리는 의미가있는 사용자 만 반환합니다. 다운 캐스팅이 가능하면 사용자는 MyClubUser 및 HisClubUser를 상속해야합니다. – thlim