2010-03-26 6 views
2

나는 이상적인 관계가 값 객체 상속과 관련이 있다고 생각한다. 불행히도 NHibernate에서 지원되지 않습니다 그래서 내가 가진 모든 솔루션을 완벽하게 될 것입니다. Hibernate (또는 Hibernate)가 쉽게 지원하지 않는 관계를 모델링하는 방법

가의 그런 말을하자

  • "항목"실체 여러 가지 형식 중 하나가 될 수있는 "위치"가.
  • 이러한 형식은 필드가 겹치지 않고 완전히 다릅니다.
  • 한 위치에서 다른 위치로 변환하지 않고 데이터에 제공된 형식으로 각 위치를 처리합니다.
  • 각 항목에는 정확히 하나의 위치가 있습니다.
  • "SpecialItem"은 정확히 두 개의 Locations가 있다는 점에서 고유 한 Item의 하위 유형입니다.
  • "그룹"엔티티는 항목을 집계합니다.
  • "LocationGroup"은 (는) 그룹의 하위 유형입니다.
  • LocationGroup에는 위에서 설명한 형식 중 하나 일 수있는 단일 위치가 있습니다. 내가 그룹에 의해 항목에 관심이 있지만
  • , 나는 관계없이 그들이에있는 그룹의 같은 위치에있는 모든 항목을 찾을 수있는에 관심이 있어요.

나는 수에 대한 사과 위에 나열된 규정을 따르지 만 더 이상 단순화하면 상황의 어려움을 반영하지 못할 것입니다. 다음 다이어그램으로 할 수있는 방법을 위입니다 :

  • 나는 슈퍼 타입이 아닌 하위 유형을 참조, 다형 위치 치료 :

    Mapping Dilemma Diagram http://www.freeimagehosting.net/uploads/592ad48b1a.jpg

    위의 분석, 나는 다음과 같은 관측을합니다.

  • 논리적으로 위치는 엔티티가 아니라 값 개체이어야합니다. 동일한 값을 가진 두 Location 개체를 구별하는 것이 의미가 없기 때문입니다. 따라서 Locations 간의 동일성은 식별자가 아닌 필드 비교를 기반으로해야합니다. 또한 값 객체는 변경 가능해야하며 공유 참조는 허용되지 않아야합니다.
  • NHibernate (또는 Hibernate)를 사용하면 일반적으로 클래스의 필드가 포함 된 클래스를 나타내는 데이터베이스 테이블에 직접 매핑되는 "component"키워드를 사용하여 값 객체를 매핑합니다. 즉, 데이터베이스에는 별도의 "Locations"테이블이 없으므로 Locations에는 식별자가 없습니다.
  • NHibernate (또는 Hibernate)는 현재 값 객체에 대한 상속을 지원하지 않습니다. 내가 그들을 보는 바와 같이

내 선택 사항은 다음과 같습니다

  1. 이 위치 값 개체 수 및 개체로 매핑해야한다는 사실을 무시한다.
    NHibernate가 엔티티 상속을 지원하므로 상속 매핑 문제를 처리 할 것입니다. 단점은 내가 앨리어싱 문제를 다루어야한다는 것입니다.(즉, 여러 객체가 동일한 위치에 대한 참조를 공유하는 경우 하나의 객체의 위치에 대한 값을 변경하면 동일한 위치 기록에 대한 참조를 공유하는 다른 객체에 대한 위치가 변경 될 수 있습니다.) 가능한 경우이를 피하고 싶습니다. 또 다른 단점은 엔티티가 일반적으로 ID로 비교된다는 것입니다. 즉, 두 필드는 모두 이 아닌이 같다고 간주됩니다. 이것은 비즈니스 관점에서 볼 때 무용지물이며 받아 들일 수 없을 것입니다.
  2. 위치를 단일 클래스로 병합하여 위치에 대한 상속 관계가 더 이상 존재하지 않도록합니다. 이렇게하면 NHibernate에서 "컴포넌트"매핑을 사용하여 Locations를 값 객체로 쉽게 처리 할 수 ​​있습니다. 이 경우의 단점은 도메인 모델이 약하고 깨지기 쉽고 유지하기가 쉽지 않다는 것입니다.
  3. "component"키워드를 사용하지 않고 위치 필드를 포함 된 엔티티의 테이블에 강제로 매핑하려면 hbm 파일에서 일부 "광고 소재"매핑을 수행하십시오.이 접근법은 콜린 잭 here에 설명되어 있습니다. 내 상황은 SpecialItem에 두 번째 위치가 있고 사실상 다른 엔티티 인 LocatedGroup에도 Locations가 있다는 사실 때문에 그가 설명하는 것보다 더 복잡합니다. 아마 작동시킬 수는 있지만 맵핑은 비 직관적이어서 다른 개발자가 이해하고 유지하기가 어려울 것입니다. 또한 이러한 까다로운 매핑은 Fluent NHibernate를 사용하여 가능하지 않을 것이라고 생각합니다. 적어도이 상황에서이 도구를 사용하는 장점을 활용할 것입니다.

확실하게 다른 유사한 상황이 발생했습니다. 나는 "거기에 있었다"는 누군가가 지혜를 공유 할 수 있기를 바라고 있습니다. :-)

그래서 여기에 문제가 있습니다.이 상황에서 어느 접근 방식을 선호해야합니까? 왜? 제가 고려하지 않은 더 나은 선택이 있습니까? 서로 다른 위치 형식이 겹치는 분야가없는 경우, 서브 클래스 계층 구조에 대한 그들에게 후보를 만들 것 그들의 공통점은 무엇

답변

1

불과 몇 관찰/질문 ...

  • 입니까? 실제로 기본 클래스 Location에 대한 공용 인터페이스를 정의 할 수 있습니까?
  • TypeBLocation에 필적하는 TypeALocation입니까?
  • 은 같은 유형의 SpecialItem의 두 위치이거나 혼합 될 수 있습니까?
  • 항목의 위치를 ​​다른 유형 런타임으로 변경할 수 있습니까?

위 상태로 값 개체는 다형성 일 수 없습니다. 당신이 묘사 한 바를 토대로, 나는 당신이 위치들을 다형 적으로 어떻게 다룰 수 있는지를 보지 못했습니다.

업데이트 당신이 당신의 위치 타입의 공통 기본 인터페이스를 정의 할 수없는 경우는 관계없이 ORM 여부가 있는지의 시도하고 그들이 다형 적 치료가 매우 어색하다. 아래 예제를 보면서 내가 살고있는 실제 위치에 대한 정보에 액세스하기 위해 거리 주소 나 위도/경도 좌표로 추방해야했습니다. Polimorphism은 다운 캐스트 (및 유형 필드의 스위치 등)가 필요하지 않도록 정확하게 의미합니다!당신은, 나는 그것이 하나 (거의 놀라운 일 없음) 좋아하지 않아

  1. 것처럼 :이 모든 고려하여

    은 옵션을 보면 당신은 위의 설명합니다.

  2. 위치 유형이 많지 않으면 실행 가능한 옵션 일 수 있으며 필요한 모든 유형을 구현했다고 합리적으로 판단 할 수 있습니다. 이 경우 도메인 클래스는 사실상 유형 필드가있는 C 공용어의 아날로그입니다. 사용하는 것이 약간 어색하지만, 다형성 시도는 훨씬 더 어색할 것입니다.
  3. 언젠가 애완 동물 프로젝트에서 실험 해 볼만한 흥미로운 아이디어이지만, 제작 코드에서 이러한 트릭을 원한다고 확신하지는 못합니다. 나는 또한 특정 하위 클래스에 구성 요소를 매핑하는 사용자 지정 매핑 유형을 사용하여 수행 할 수 있다고 생각합니다. 그런데 다시 이러한 호환되지 않는 유형을 유형 계층 구조에 맞추려고합니다 ...이 경로를 시도하는 유일한 이유는 많은 위치 유형 및/또는 새로운 유형이 미래에 나타날 수 있다는 것입니다.
+0

공통점은 두 가지 위치 유형 모두 동일한 요구를 충족한다는 것입니다. 항목에는 위치가 있어야하지만 해당 요구 사항은 하위 유형으로 채울 수 있습니다. 위치 상위 유형은 추상적입니다. 하위 유형을 소유하는 엔티티는 부속 유형 중 하나를 수용하기 위해 상위 유형을 참조합니다. 비교를 위해 어떻게 사는 곳을 지정할지 생각해보십시오. 번지 나 위도/경도 조합을 지정할 수 있습니다. 두 가지 형식 모두 동일한 작업을 수행하지만 공통 필드는 없습니다. 2 개의 SpecialItem Locations는 서로 다른 유형일 수 있습니다. – MylesRip

+0

값 개체를 다형 적으로 처리하는 데는 개념적 문제가 있다고 생각하지 않습니다. ORM에 의해 현재 지원되지 않습니다. 항목의 위치가 * 값 *을 변경할 수 있습니다. 도메인 모델에서, 이것은 참조 객체를 새로운 불변 ​​위치로 대체함으로써 달성 될 수있다 (값 객체 접근법을 가정 함). 런타임에 항목의 위치를 ​​다른 * 유형 *으로 변경하면이 응용 프로그램에서 지원되지 않습니다. – MylesRip

+0

위치에 동작이 많지 않습니다. (나는 대부분의 가치 객체가 유효성 검사, 표시, 정렬 등과 ​​같은 것들보다 많은 행동을하지 않는다고 생각한다.) 사실 비즈니스 요구 사항을 처리 할 방법이 필요하다. 사실 여러 위치 포맷이있다. 위치가 필요할 때마다 유효합니다. 위와 같은 상황에서 옵션 2를 구현 하시겠습니까? ... 아니면 완전히 다른 무언가? – MylesRip

관련 문제