2009-11-17 2 views
2

외래 키와 고정 값을 키/맵핑 인수로 사용하여 콜렉션 (유형 맵)을 맵핑하려고합니다.상수 키로 Hibernate 맵 콜렉션

제품 유형과 제품 이름 등을 저장하는 언어 테이블이 여러 개 있습니다.

이제 액세서리가 들어있는 액세서리 테이블이 있다고 가정하면 액세서리 이름이 language.id = accessory.id 및 language.type = 'accessory'인 언어 테이블에 저장됩니다. 지도 키는 언어 코드 문자열 인 language.lang 필드 여야합니다.

지금 내가 뭘했는지에 상관없이 "language.type = 'accessory'"부분을 올바르게 가져올 수 없으며 여러 키 요소가 마음에 들지 않으므로 어쨌든 요소를 ​​허용하지 않습니다. .

는 또한 기본적으로 일정한 세트로, 외래 키 등의 복합 구성 요소와 그것을 시도했지만, 그건 정말 작업 중 하나를하지 않았다 : 해당 클래스와 물론

<class name="AccessoryTypes" 
    table="accessorytypes"> 
    <id name="id" column="id" type="java.lang.Long" unsaved-value="0"> 
     <generator class="identity"></generator> 
    </id> 
    <map name="Name" table="ProductCode"> 
     <key column="CompositeId" /> 
     <map-key column="Language" type="string" /> 
     <one-to-many class="ProductCode" /> 
    </map> 
</class> 

<class name="Language" 
     table="Language"> 
     <composite-id name="compositeId" class="languageKey"> 
      <key-property name="Type"></key-property> 
      <key-property name="Id"></key-property> 
     </composite-id> 
     <property name="Lang" type="string"></property> 
     <property name="Value"></property> 
    </class> 

합니다. 이 접근 방식은 오류를주지 않지만 Accessory 클래스의 HashMap을 채우지는 않습니다 ...

어떤 도움을 주셔서 감사합니다, 감사합니다. ,

<class name="AccessoryTypes" 
     table="accessorytypes"> 
    <id name="id" column="id" type="java.lang.Long" unsaved-value="0"> 
     <generator class="identity"></generator> 
    </id> 
    <properties name="CompositeId" > 
     <property name="id" /> 
     <property name="Type" formula="'accessory'" /> 
    </properties> 
    <map name="Name" table="ProductCode"> 
     <key property-ref="CompositeId" /> 
     <map-key column="Language" type="string" /> 
     <one-to-many class="ProductCode" /> 
    </map> 
</class> 

<class name="com.swissclick.wesco.web.model.ProductCode" 
     table="ProductCode"> 
    <composite-id class="com.swissclick.wesco.web.model.ProductCodeKey" mapped="true"> 
     <key-property name="Type"></key-property> 
     <key-property name="id"></key-property> 
    </composite-id> 
    <property name="Language" type="string"></property> 
    <property name="Value"></property> 
</class> 

을하지만이 작동하지 않습니다 ziodberg이 제안

는 [편집] 지금이 등을 먼저하지로, property-ref 속성으로 시도 하나, 그것은 구글에 어떤 도움이되는 정보를 설정하지 않는

org.hibernate.MappingException: collection foreign key mapping has wrong number of columns: AccessoryTypes.Name type: component[Id,Type] 

을 제공합니다.

어떤 아이디어가 있습니까?

+0

콜렉션에서 column = "compositeId"를 참조했기 때문일까요? 대신 property-ref = "compositeId"를 사용하는 것이 어떻습니까? – Zoidberg

답변

2

편집. 그래서 저는 여러분의 테이블 구조에 대해 아직도 명확하지 않습니다. 그것은 초기 답을 쓸 때 저를 던졌습니다.

Id -- this is a PK of entity (e.g. Accessory) this entry provides localization info for 
Type -- string constant describing entity type (e.g. "accessory") 
Language -- language code 
Value -- actual localized string 

맞아 대해 보입니까 :

나의 이해는 같이 당신의 Language 테이블 모양의 무언가가 있다는 것입니다? 그렇다면 동일한 엔터티 내에 개의 필드를 어떻게 현지화 할 것인지에 대한 질문이 제기됩니다. 최소한 속성 (필드) 이름에 연결하는 다른 열이 있어야하지 않습니까? 여하튼

, <formula> 실제로 그래서 여기에 옵션이 매우 제한되어 <key> (나는 그이다 맹세 할 수있다)의 일부로 지원되지 않습니다

  1. 사용 custom loader - 이것은 아마도 가장입니다 간단한 접근법.
  2. Accessory 테이블에 type을 실제 열로 추가하고이를 합성 ID의 일부로 매핑하십시오. 복합 키를 사용하여 Language지도를지도로 표시 할 수 있습니다. 작동해야하지만 오히려 추한 것입니다.
  3. 접근 방식을 다시 생각해보십시오. 실제로은 매번 언어 맵을로드해야합니까? 현재 언어에 대해 별도의 쿼리 (또는 심지어 get()이 적절한 복합 ID라고 가정)를 수행하는 것이 더 쉽고 적절한 캐싱 구성으로 훨씬 빠릅니다. 의

    먼저 저를 명확히이하자 -를 내가 지역화 된 문자열을 사용자가 편집 할 수 런타임에있다 있으리라 믿고있어 :

업데이트 위의 # 3에서 자세히 설명합니다. 그렇지 않은 경우 테이블을 모두 버리고 리소스 번들을 사용하는 것이 좋습니다.

내가 type, id, language과 별도의 항목으로 Language지도 및 거라고 복합 ID의 일부로 property_name를 (여러 속성에 대해이 작업을 수행 할 필요가있는 경우). 엔티티의 현지화 가능 실제 속성 (예 : ProductName, AccessoryType)은 일시적입니다. 당신은 심지어 event listener 현재 선택된 언어는 전 세계적으로 얻을 수 있다고 가정 그렇게 (글로벌을 통해 또는 시내 전화 스레드) 수

AccessoryType accessory = ...; 
Language language = (Language) session.get(Language.class, 
new LanguageKey("accessory", accessory.id, "en_US", "productName")); 
accessory.setProductName(language.getValue()); 

- 그것을 : 당신은 수동으로 뭔가를 수행하여 엔티티에 해당하는 지역화 된 문자열을로드 할 수 있습니다 그러면 모든 엔티티에 자동으로 마법이 적용됩니다. 언어 테이블이 상당히 작은 경우 최대 절전 모드 cache it을 가질 수 있으며 데이터베이스 히트가 발생하지 않습니다.

+0

실제로 시도한 첫 번째 작업 이었지만 Hibernate 3에서는 작동하지 않는 것처럼 보였습니다. 핵심 요소는 수식 요소를 사용하지 않습니다. 이렇게하면 "요소 유형의 내용"키가 "(열) *"과 일치해야합니다. " 오류. – Zenon

+0

네, 언어 표가 그 모양입니다. 글쎄, 퍼포먼스는 실제로 문제가되지 않는다. (나는 결코 알지 못할 것이다.) 그래서 모든 데이터베이스 객체가 그들과 함께 다른 국제화 된 문자열을 가지고 있다면 꽤 우아 할 것이라고 생각했다. 언어). 아마도 옵션 1을 사용 하겠지만 3을 자세히 설명해 주시겠습니까? "직접 가져 오기()"로 정확히 무엇을 의미합니까? 오, 그리고 당신의 노력에 미리 감사드립니다.이 문제는 지난 며칠 동안 견디고 있습니다. – Zenon

+0

도움을 많이 주셔서 감사합니다. 결국 Java/Hibernate/Spring 프로젝트가 처음입니다. 고객이 명시 적으로 데이터베이스를 요청하지 않았 더라면 나는 리소스 번들을 사용했을 것입니다. 이벤트 리스너를 사용하는 get() 메서드는 훌륭하게 들리지만 조금 더 많은 작업이 이루어 지지만 장기적으로는 훨씬 덜 효과적입니다. 이벤트 리스너가 특정 클래스 (+ 파생) 관련 이벤트 만들을 수있게하는 방법이 있습니까? 다른 사람이 같은 문제를 겪는다면 필자의 해결책으로 내 질문을 업데이트 할 것입니다. – Zenon