Отображение Hibernate-соединения для множества к одному с несколькими столбцами - PullRequest
2 голосов
/ 05 января 2012

Я пытаюсь использовать Hibernate для отображения таблицы как набора DTO в другой DTO.У меня проблемы, потому что мне нужно сделать отображение с использованием двух столбцов.Может, кто-нибудь скажет мне, что написать в файле отображения hibernate, чтобы выполнить сопоставление, так как кажется, что независимо от того, что я вставил в часть сопоставления присоединения, он не принимается как допустимый формат.

DTO, который я пытаюсь сопоставить с Hibernate:

открытый класс CoverageDTO extends 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 - перечисляет, какие специальные правила должны применяться к поставщику иd для каких рынков.

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_special_rules в таблицу покрытия, используя информацию в таблице supplier_coverage_special_rules, т.е. путем сопоставления столбцов 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>

Есть идеи о том, как сделать это сопоставление?

(и да, янеобходимо сопоставить идентификатор_поставщика и идентификатора_процесса, а не идентификатор_покрытия для различных других требований).

РЕДАКТИРОВАТЬ

В другом месте я обнаружил предложение использовать свойства для определения ключачто соединение должно быть выполнено, например:

<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: в сопоставлении внешнего ключа коллекции указано неверное число столбцов: net.dtopath.CoverageDTO.specialRules тип: component[SupplierID, NETWORKID] "

1 Ответ

2 голосов
/ 11 января 2012

Я понял это, и это было действительно очень просто:

<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, он знает, из какой таблицы происходит этот объект.

...