我正在尝试使用Hibernate将一个表作为一组DTO映射到另一个DTO。我遇到了麻烦,因为我需要使用两列进行映射。请问我可以告诉我在hibernate映射文件中要写什么来进行映射,因为无论我在映射的'join'部分放置什么,它都不被接受为有效格式。
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表中的信息将supplier_special_rules映射到coverage表中,即匹配MARKET_ID和SUPPLIER_ID列。我虽然下面的映射会这样做,但它似乎不是一个有效的映射语法。
<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>
但这会产生错误“org.hibernate.MappingException:collection外键映射列数错误:net.dtopath.CoverageDTO.specialRules类型:component [supplierID,networkID]”
答案 0 :(得分: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知道类ProviderRpecialRuleDTO,它知道该对象来自哪个表。