2

I'm trying to use Hibernate to map a table as a set of DTOs into another DTO. I'm running into trouble as I need to do the mapping using two columns. Please could somone tell me what to write in the hibernate mapping file to do the mapping as it seems no matter what I put in the 'join' part of the mapping, it is not accepted as a valid format.

The DTO I'm trying to map with hibernate:

public class CoverageDTO extends BaseDTO {

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

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

}

The underlying SQL tables are:

Supplier table, lists which suppliers we have - primary key is SUPPLIER_ID, other details irrelevant.

Market table, lists different markets that suppliers may be able to provide their products in - primary key is MARKET_ID, other details irrelevant.

Coverage table - lists which markets suppliers can reach, and what the price/currency is for that supplier for that market

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 table - lists the special rules that can be applied to suppliers.

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 - lists which special rules should be applied for a supplier and for which markets.

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;

So thinking at an SQL level, I need to map the supplier_special_rules into the coverage table using the information in the supplier_coverage_special_rules table i.e. by matching the MARKET_ID and SUPPLIER_ID columns. I though the mapping below would do it, but it doesn't seem to be a valid mapping syntax.

<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>

Any ideas on how to do this mapping?

(and yes I need to map on supplier_ID and market_ID rather than coverage_ID for various other requirements).

EDIT

I found elsewhere a suggestion that I should be using properties to define the key that the join should be done on e.g.:

<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>

but this give an error "org.hibernate.MappingException: collection foreign key mapping has wrong number of columns: net.dtopath.CoverageDTO.specialRules type: component[supplierID,networkID]"

1 Answer 1

2

I figured it out and it was actually really simple:

<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>

Each step of the join only requires one column for the join. I was doing it wrong by trying to tell hibernate about two columns at once.

Also I had missed that because Hibernate knows about the class SupplierSpecialRuleDTO, it knows which table that object comes from.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.