2012-01-05 116 views
2

我试图使用Hibernate将表映射为一组DTO到另一个DTO。我遇到了麻烦,因为我需要使用两列进行映射。请大家告诉我在hibernate映射文件中写什么来完成映射,因为无论我放入映射的“连接”部分,它都不会被接受为有效格式。Hibernate连接映射多对一,多列

的DTO我试图与Hibernate映射:

公共类CoverageDTO延伸BaseDTO {

private SupplierDTO supplierDTO; 
private MarketDTO marketDTO; 
private Float price; 
private String currency; 

private Set<SpecialRuleDTO> specialRules = new HashSet<SpecialRuleDTO>(0); 

}

基础SQL表是:

供应商表,列出我们有哪些供应商 - 主键是SUPPLIER_ID,其他细节无关紧要。

市场表列出供应商可以提供其产品的不同市场 - 主键是MARKET_ID,其他细节无关紧要。

覆盖表 - 这市场的供应商能达到清单,什么价格/币种是针对供应商对于市场

CREATE TABLE coverage (
    COVERAGE_ID int(10) unsigned NOT NULL auto_increment, 
    SUPPLIER_ID int(10) unsigned NOT NULL, 
    MARKET_ID int(10) unsigned NOT NULL, 
    PRICE float default NULL, 
    CURRENCY varchar(5) default NULL, 
    PRIMARY KEY USING BTREE (COVERAGE_ID) 
) DEFAULT; 

supplier_special_rules表 - 列出了可以应用到供应商的特殊规则。

CREATE TABLE supplier_special_rules (
    SUPPLIER_SPECIAL_RULE_ID bigint(20) unsigned NOT NULL auto_increment, 
    SUPPLIER_ID bigint(20) unsigned NOT NULL, 
    NAME varchar(128) NOT NULL, 
    TYPE varchar(128) NOT NULL, 
    VALUE float NOT NULL, 
    PRIMARY KEY (SUPPLIER_SPECIAL_RULE_ID) 
) DEFAULT; 

supplier_coverage_special_rules - 列出哪些特殊规则应适用于供应商和哪些市场。

CREATE TABLE supplier_coverage_special_rules (
    SUPPLIER_COVERAGE_SPECIAL_RULE_ID bigint(20) unsigned NOT NULL auto_increment, 
    MARKET_ID bigint(20) unsigned NOT NULL, 
    SUPPLIER_SPECIAL_RULE_ID bigint(20) unsigned NOT NULL, 
    PRIMARY KEY (SUPPLIER_COVERAGE_SPECIAL_RULE_ID) 
) DEFAULT; 

所以在SQL层次的思考,我需要使用在supplier_coverage_special_rules表即信息通过匹配MARKET_ID和SUPPLIER_ID列于supplier_special_rules映射到覆盖表。我虽然下面的映射会做到这一点,但它似乎不是一个有效的映射语法。

<hibernate-mapping package="net.dtopath"> 
    <class name="CoverageDTO" table="coverage"> 
     <id column="COVERAGE_ID" name="ID"> 
      <generator class="native"/> 
     </id> 

     <many-to-one class="net.dtopath.SupplierDTO" column="SUPPLIER_ID" name="supplierDTO"/> 

     <many-to-one class="net.dtopath.MarketDTO" column="MARKET_ID" name="marketDTO"/> 

     <property name="price" type="float"> 
      <column name="PRICE" not-null="false"/> 
     </property>  

     <property name="currency" type="string"> 
      <column name="CURRENCY" not-null="false"/> 
     </property> 

     <!-- Start of the bit that needs editing as it's wrong --> 
     <join table="SUPPLIER_COVERAGE_SPECIAL_RULES"> 
      <key> 
       <column name="SUPPLIER_ID" not-null="true" /> 
       <column name="MARKET_ID" not-null="true" /> 
      </key> 
      <many-to-one name="specialRules" column="SUPPLIER_SPECIAL_RULE_ID" class="SupplierSpecialRuleDTO" not-null="true" /> 
     </join> 
     <!-- End of the bit that needs editing as it's wrong --> 
    </class> 
</hibernate-mapping> 

有关如何进行此映射的任何想法?

(是的,我需要映射在supplier_ID和market_ID上,而不是coverage_ID以满足各种其他要求)。

编辑

我在别处找到了,我应该使用属性来定义的连接应在如完成的关键建议:

<properties name="keysCoverageSpecialRules"> 
    <property name="supplierID" column="SUPPLIER_ID" insert="false" update="false"/> 
    <property name="marketID" column="MARKET_ID" insert="false" update="false"/> 
</properties> 

<set name="specialRules" table="SUPPLIER_COVERAGE_SPECIAL_RULES"> 
    <key property-ref="keysCoverageSpecialRules"> 
    </key> 
    <many-to-many class="SupplierSpecialRuleDTO" unique="true" column="SUPPLIER_SPECIAL_RULE_ID"/> 
</set> 

但这给出一个错误“组织。 hibernate.MappingException:收集外键映射具有错误的列数:net.dtopath.CoverageDTO.specialRules类型:成分[供应商ID,网络ID]”

回答

2

我想通了,它实际上很简单:

<set name="specialRules" table="SUPPLIER_COVERAGE_SPECIAL_RULES" > 
    <key column="MARKET_ID" /> 
<many-to-many class="SupplierSpecialRuleDTO" unique="true" column="SUPPLIER_SPECIAL_RULE_ID" /> 
</set> 

连接的每一步只需要一列用于连接。我试图通过一次告诉hibernate关于两列来做错了。

另外我错过了,因为Hibernate知道类SupplierSpecialRuleDTO,它知道哪个对象来自哪个表。