Razavi Razavi - 9 months ago 44
Java Question

How to define hibernate mapping file with Table Per Subclass and composite-id?

I am using hibernate3 in my java app to access Oracle 10g, and attempting to create a VPN class that extends an Subscriber class in my program, and the table of these two entity is exist in database. Primary key in these table is same (subscriberId) and finally I'm going to create a hbm mapping file for them.

But after a hour it became so complicated to create a mapping file for VPN class. How can I define hbm file for VPN class?

Class Subcriber

public class Subscriber implements java.io.Serializable {
private SubscriberId id;
private SubscriberType subscriberType;
private Vpn vpn;
private String code;
private String account;
private String mnemonic;
private String region;
private String userAddress;
private String name;

Class VPN

public class Vpn extends Subscriber implements java.io.Serializable {

private SubscriberId id;
private Subscriber subscriber;
private long firstSsi;
private long lastSsi;

Class SubscribeID

public class SubscriberId implements java.io.Serializable {
private long ssi;
private String ccnc;

public SubscriberId() {

public SubscriberId(long ssi, String ccnc) {
this.ssi = ssi;
this.ccnc = ccnc;


public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof SubscriberId))
return false;
SubscriberId castOther = (SubscriberId) other;

return (this.getSsi() == castOther.getSsi())
&& ((this.getCcnc() == castOther.getCcnc()) || (this.getCcnc() != null
&& castOther.getCcnc() != null && this.getCcnc()

public int hashCode() {
int result = 17;

result = 37 * result + (int) this.getSsi();
result = 37 * result
+ (getCcnc() == null ? 0 : this.getCcnc().hashCode());
return result;

Answer Source

I think you should use one mapping file for both class:

<class name="Subscriber" table="SUBSCRIBER"
    <composite-id name="id"
        class=" SubscriberId">
        <key-property name="ssi" type="long">
            <column name="SSI" precision="10" scale="0" />
        <key-property name="ccnc" type="string">
            <column name="CCNC" length="200" />
    <many-to-one name="subscriberType"
        class=" SubscriberType" fetch="select">
        <column name="SUBSCRIBER_TYPE_ID" precision="2" scale="0"
            not-null="true" />
    <many-to-one name="vpn" class=" Vpn"
        <column name="VPN_CODE" precision="10" scale="0" />
        <column name="VPN_CCNC" length="200" />
    <property name="code" type="string">
        <column name="CODE" length="512" not-null="true" />
    <property name="account" type="string">
        <column name="ACCOUNT" length="64" />
    <property name="mnemonic" type="string">
        <column name="MNEMONIC" length="30" />
    <property name="region" type="string">
        <column name="REGION" length="64" />
    <property name="userAddress" type="string">
        <column name="USER_ADDRESS" length="64" />
    <property name="name" type="string">
        <column name="NAME" length="64" not-null="true" />
    <joined-subclass extends=" Subscriber"
        name=" Vpn" schema="SMDB" table="VPN">
            <column name="SSI" />
            <column name="CCNC" />
        <property generated="never" lazy="false" name="firstSsi"
            <column name="FIRST_SSI" not-null="true" precision="10"
                scale="0" />
        <property generated="never" lazy="false" name="lastSsi"
            <column name="LAST_SSI" not-null="true" precision="10" scale="0" />