We have the following object model:
A Correspondent (this could be a customer, a solictor, a surveyor etc) - table is CORRESPONDENT
A sub-class of Correspondent is Customer, which has additional fields held on another file (CUSTOMER)
A Correspondent can have a collection of addresses (current address, previous address etc) (ADDRESS)
A Customer can have a CustomerAddress, which is a sub-class of address.
The way the database is set up is like this
CORR_ADDR---------custid-----------CORRESPOND
| |
| |
| |
addrid custid
! |
! |
!
ADDRESS CUSTOMER
My question revolves around this issue. CORRESPOND is mapped in theory to ADDRESS, via the CORR_ADDR xref file (i.e. a classic many-to-many mapping). However the CORR_ADDR file is also holding additional CustomerAddress fields, as CustomerAddress is a sub-class of Address.
So to come to the question, how to I map a many to many relationship between CORREPSOND and ADDRESS, when the xref table acts both as an XREF table, and as a joined subclass of Address ?
As usual the databse structure is something we have inherited and cannot change easily.
Hibernate version:
2.17
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class name="net.targetgroup.broker.correspondent.Correspondent" table="CORRESPOND">
<id name="identifier" type="int" column="CUSTID" unsaved-value="-1">
<generator class="native" />
</id>
<property name="title" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="TITLE" length="10" />
<property name="firstName" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="FIRSTNAME" length="20" />
<property name="secondName" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="SECONDNAME" length="64" />
<property name="lastName" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="LASTNAME" length="20" />
<property name="userStamp" type="java.lang.String" column="USERSTAMP" length="10" />
<property name="preferredName" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="PREFNAME" length="20" />
<property name="emailAddress" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="EMAILADDR" length="80" />
<property name="timeStamp" type="java.sql.Timestamp" column="DATETIME" length="19" />
<property name="organization" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="ORGANIZATION" length="40" />
<property name="previousTitle" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="PREVIOUSTITLE" length="10" />
<property name="mailList" type="java.lang.String" column="MAILLIST" length="1" />
<property name="previousForename1" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="PREVIOUSFORENAME1" length="20" />
<property name="previousForename2" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="PREVIOUSFORENAME2" length="20" />
<property name="previousLastname" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="PREVIOUSLASTNAME" length="20" />
<!-- bi-directional one-to-many association to CorrAddr -->
<set name="addresses" lazy="false" inverse="true" cascade="all">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="net.targetgroup.broker.customer.CustomerAddress" />
</set>
<!-- bi-directional one-to-many association to Telephone -->
<set name="telephones" lazy="false" inverse="false" cascade="all">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="net.targetgroup.broker.correspondent.Telephone" />
</set>
<!-- bi-directional one-to-many association to Consol - most likely not needed as no consols set on correspond
<set name="consols" lazy="false" inverse="true" cascade="all">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="net.targetgroup.broker.application.Consolidation" />
</set>
-->
<!-- bi-directional one-to-one association to Contact -->
<one-to-one name="contactPreference" class="net.targetgroup.broker.correspondent.ContactPreference" outer-join="auto" />
<joined-subclass name="net.targetgroup.broker.customer.Customer" table="CUSTOMER">
<key column="CUSTID" />
<property name="userStamp" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="USERSTAMP" length="10" />
<property name="birthDate" type="java.sql.Timestamp" column="CUSBRTHDT" length="19" />
<property name="timeStamp" type="java.sql.Timestamp" column="DATETIME" length="19" />
<property name="birthPlace" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSBRTHPL" length="30" />
<property name="passWord" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSPSSWRD" length="30" />
<property name="gender" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSGENDER" length="10" />
<property name="maritalStatus" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSMARTSTS" length="30" />
<property name="numberOfDependantsAtHome" type="net.targetgroup.util.datatypes.CustomIntType" column="NODEPSHOME" length="2" />
<property name="numberOfDependants" type="net.targetgroup.util.datatypes.CustomIntType" column="CUSNODEPS" length="2" />
<property name="dependantsAges" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="DEPAGES" length="30" />
<property name="homeOwner" type="net.targetgroup.util.datatypes.CustomBooleanType" column="CUSHOMOWNR" length="1" />
<property name="mortgageArrears" type="java.math.BigDecimal" column="CUSMRTARRS" length="3" />
<property name="bankrupt" type="net.targetgroup.util.datatypes.CustomBooleanType" column="CUSBNKRPT" length="1" />
<property name="residentialArea" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSAREA" length="40" />
<property name="alias" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSTALIAS" length="30" />
<property name="maidenName" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSMAIDNM" length="20" />
<property name="residentialStatus" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSRESSTAT" length="40" />
<property name="propertyType" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSPROPTYP" length="40" />
<property name="ownershipType" type="java.lang.String" column="CUSOWNTYP" length="40" />
<property name="repossession" type="net.targetgroup.util.datatypes.CustomBooleanType" column="CUSREPOSS" length="1" />
<property name="defaultNotice" type="net.targetgroup.util.datatypes.CustomBooleanType" column="CUSDEFAULT" length="1" />
<property name="employmentStatus" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSEMPSTAT" length="40" />
<property name="nationality" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="NATIONALITY" length="40" />
<property name="involuntaryAgreement" type="net.targetgroup.util.datatypes.CustomBooleanType" column="CUSIVA" length="1" />
<property name="countryOfResidence" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="COUNTRYOFRESIDENCE" length="40" />
<property name="nationalInsuranceNo" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="NATIONALINSURANCE" length="30" />
<property name="taxDistrict" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="TAXDISTRICT" length="40" />
<property name="firstTimeBuyer" type="net.targetgroup.util.datatypes.CustomBooleanType" column="FIRSTTIMEBUYER" length="1" />
<property name="smoker" type="net.targetgroup.util.datatypes.CustomBooleanType" column="SMOKER" length="30" />
<property name="relation" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="RELATION" length="30" />
<set name="employments" lazy="false" inverse="true" cascade="all">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="net.targetgroup.broker.customer.Employment" />
</set>
<set name="transactions" lazy="false" inverse="true" cascade="all">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="net.targetgroup.broker.customer.Transaction" />
</set>
<set name="judgements" lazy="false" inverse="true" cascade="all">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="net.targetgroup.broker.customer.Judgement" />
</set>
<set name="lifeAssurances" lazy="false" inverse="true" cascade="all">
<key>
<column name="APPID" />
</key>
<one-to-many class="net.targetgroup.broker.application.LifeAssurance" />
</set>
<!-- bi-directional many-to-many association to Custlink -->
<set name="correspondents" lazy="false" inverse="true" cascade="all-delete-orphan" table="CUSTLINK">
<key>
<column name="CUSTID" />
</key>
<many-to-many class="net.targetgroup.broker.correspondent.Correspondent" column="LINKCUST" />
</set>
<set name="lenderAccountGroups" lazy="false" inverse="true" cascade="all-delete-orphan">
<key>
<column name="CUSTID" />
</key>
<one-to-many class="net.targetgroup.broker.customer.LenderAccountGroup" />
</set>
<joined-subclass name="net.targetgroup.broker.customer.Applicant" table="CUST_APPL">
<key>
<column name="CUSTID" />
</key>
<property name="applicationIdentifier" column="APPID" ></property>
<property name="type" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="CUSTTYP" />
</joined-subclass>
</joined-subclass>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<class name="net.targetgroup.broker.address.Address" table="ADDRESS">
<id name="identifier" type="int" column="ADDRID" unsaved-value="-1">
<generator class="native" />
</id>
<property name="addressLines" type="net.targetgroup.broker.address.AddressLinesUserType">
<column name="ADDR01" />
<column name="ADDR02" />
<column name="ADDR03" />
<column name="ADDR04" />
<column name="ADDR05" />
</property>
<property name="postcode" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="POSTCODE" length="8" />
<property name="userStamp" type="java.lang.String" column="USERSTAMP" length="10" />
<property name="timeStamp" type="java.sql.Timestamp" column="DATETIME" length="19" />
<joined-subclass name="net.targetgroup.broker.customer.CustomerAddress" table="CORR_ADDR">
<key>
<column name="ADDRID" />
</key>
<property name="customerIdentifier" type="java.math.BigDecimal" column="CUSTID" length="9" />
<property name="userStamp" type="java.lang.String" column="USERSTAMP" length="10" />
<property name="addressType" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="ADDRTYPE" length="30" />
<property name="timeStamp" type="java.sql.Timestamp" column="DATETIME" length="26" />
<property name="movedInDate" type="java.sql.Timestamp" column="MOVEDIN" length="26" />
<property name="votersRoll" type="net.targetgroup.util.datatypes.CustomBooleanType" column="VOTERSROLL" length="1" />
<property name="movedOutDate" type="java.sql.Timestamp" column="MOVEDOUT" length="26" />
<property name="votersStartDate" type="java.sql.Date" column="VOTERSIN" length="10" />
<property name="ownStatus" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="OWNERSHIPSTATUS" length="40" />
<property name="votersEndDate" type="java.sql.Date" column="VOTERSOUT" length="10" />
</joined-subclass>
</class>
</hibernate-mapping>