I'm having trouble building some mappings to my legacy database. I Can't work out how to build one-to-many mappings where both tables have natural composite keys. I have a lot of these to build, but once I've got one working, the rest should be easy.
A simple example. I have two tables; currency and exchange rate. The essential parts of the DDL looks like this:
Code:
Create table NIADATA/MACPFCC0
(
CCCMCC DECIMAL ( 3, 0) NOT NULL WITH DEFAULT ,
CCISCD CHARACTER ( 3) NOT NULL WITH DEFAULT ,
);
Create table NIADATA/MACPFCR0
(
CRCMCC DECIMAL ( 3, 0) NOT NULL WITH DEFAULT ,
CRISCD CHARACTER ( 3) NOT NULL WITH DEFAULT ,
CREXDT DECIMAL ( 7, 0) NOT NULL WITH DEFAULT ,
);
(I'm showing only the key columns here. Both tables also have a bunch of other non-key columns, but I've stripped those out for the purposes of this explanation.) Note that the column names have different prefixes, though the last four characters are the same. I'm not in a position to make
any changes to the existing database.
Now, building the mapping for the first of these tables alone was simple enough. Once Max helped me out with a separate issue with user types, that is. ;-)
Code:
<hibernate-mapping>
<class name="uk.co.trisystems.morph.currency.CurrencyDAO" table="MACPFCC0">
<meta attribute="class-description">
Details of a currency.
</meta>
<composite-id name="CurrencyPK" class="uk.co.trisystems.morph.currency.CurrencyPK">
<key-property name="company" type="integer" column="CCCMCC">
<meta attribute="field-description">Currency Company</meta>
<key-property name="iso" type="string" length="3" column="CCISCD">
<meta attribute="field-description">ISO Currency Code</meta>
</key-property>
</composite-id>
</class>
</hibernate-mapping>
Now I'm trying to add a mepping to the 2nd table, and to make the two tables refer to one another.
I think I need to add something like this to the currency mapping:
Code:
<list name="exchangeRates" table="MACPFCR0">
<key column="??????"/>
<index column="CREXDT"/>
<one-to-many class="uk.co.trisystems.morph.currency.ExchangeRateDAO"/>
</list>
But I don't know what to put into the ?????? bit.
As for the exchange rate mapping, I tried this:
Code:
<hibernate-mapping>
<class name="uk.co.trisystems.morph.currency.ExchangeRateDAO" table="MACPFCR0">
<meta attribute="class-description">
Currency exchange rate.
</meta>
<composite-id name="ExchangeRatePK" class="uk.co.trisystems.morph.currency.ExchangeRatePK">
<key-property name="currency" type="uk.co.trisystems.morph.currency.CurrencyPK">
<meta attribute="field-description">Currency</meta>
<column name="CRCMCD"/>
<column name="CRISCD"/>
</key-property>
<key-property name="date" type="uk.co.trisystems.morph.user_type.ImacsDateType" column="CREXDT">
<meta attribute="field-description">Exchange Rate Date</meta>
</key-property>
</class>
</hibernate-mapping>
This generates OK, but when I try to retrieve data through it I get:
Code:
Exception in thread "main" net.sf.hibernate.MappingException: identifier mapping has wrong number of columns: uk.co.trisystems.morph.currency.ExchangeRateDAO type: uk.co.trisystems.morph.currency.ExchangeRatePK
at net.sf.hibernate.mapping.RootClass.validate(RootClass.java:171)
at net.sf.hibernate.cfg.Configuration.validate(Configuration.java:633)
at net.sf.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:799)
at uk.co.trisystems.morph.currency.ExchangeRateDAODemo.main(ExchangeRateDAODemo.java:39)
I'm running Hibernate 2.1.8.