voncuver
voncuver

Reputation: 75

Hibernate OneToMany, natural PK

I've got problem with setting up OneToMany relationship.

My DB schema:

TABLE PARENT (
VENDOR,
CHANNEL,
CREATEDATE,
REFID,
...
)
UNIQUE INDEX PK_PARENT (VENDOR, CHANNEL, CREATEDATE, REFID)

TABLE CHILD (
REFID,
NAME,
)
UNIQUE INDEX PK_CHILD (REFID, NAME)

And Java class

public class Parent {
    String vendor;
    String channel;
    Date createdate;
    Long refid;
    List<Child> childs;
    ...
}

public class Child {
    Long refid;
    String name;
}

My problem is that I can not develop proper mapping for this classes. For consistent reasons I'm forced to use hbm xml. I was able to map it as two separate entities.

<hibernate-mapping>
<class name="Parent" table="PARENT">
    <composite-id >
        <key-property name="vendor" type="string">
            <column name="VENDOR" />
        </key-property>
        <key-property name="vendor" type="string">
            <column name="CHANNEL" />
        </key-property>
        <key-property name="vendor" type="Date">
            <column name="CREATEDATE" />
        </key-property>
        <key-property name="vendor" type="Long">
            <column name="REFID" />
        </key-property>
    <composite-id />
    <list name="childs" table="CHILD" lazy="true" fetch="select">
        <key column="REFID" />
        <index column="REFID" />
        <one-to-many class="Child" />
    </list>
</class>

<class name="Child" table="CHILD">
    <composite-id >
        <key-property name="vendor" type="Long">
            <column name="REFID" />
        </key-property>
        <key-property name="name" type="string">
            <column name="NAME" />
        </key-property>
    <composite-id />
</class>
</hibernate-mapping>

I get exception:

Caused by: org.hibernate.MappingException: Foreign key (FK_9897tr114hxkewktsi9vb92x6:CHILD[REFID])) must have same number of columns as the referenced primary key (PARENT[VENDOR,CHANNEL,CREATEDATE,REFID]) 
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:110)
    at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:93)
    at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1818)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1741)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)

Any thoughts on that?

Upvotes: 0

Views: 249

Answers (2)

Abdullah G&#252;rsu
Abdullah G&#252;rsu

Reputation: 3186

Change the property names according to java class fields in your hibernate configuration xml file. If you have a "channel" field in your java class, then it should be named as "channel" in your hbm configuration although it is a part of composite primary key.

<class name="Parent" table="PARENT">
<composite-id >
    <key-property name="vendor" type="string">
        <column name="VENDOR" />
    </key-property>
    <key-property name="channel" type="string">
        <column name="CHANNEL" />
    </key-property>
    <key-property name="createdate" type="Date">
        <column name="CREATEDATE" />
    </key-property>
    <key-property name="refid" type="Long">
        <column name="REFID" />
    </key-property>
<composite-id />
<list name="childs" table="CHILD" lazy="true" fetch="select">
    <key column="REFID" />
    <index column="REFID" />
    <one-to-many class="Child" />
</list>

Also, you should define manyToOne relationship in the other side of mapping. And there can be a Parent instance in the child class properly.(Not just an ID)

Upvotes: 1

slesh
slesh

Reputation: 2007

Because your Child entity have a complex key, therefore in the Parent entity you need specify foreign key as complex also.

Upvotes: 1

Related Questions