views:

48

answers:

1

I have the below tables.

create table logical_id_seq (
    logical_id int auto_increment,
    primary key(logical_id)
);

create table mytable (
    physical_id int auto_increment,
    logical_id int not null references parent(logical_id),
    data varchar(20),
    primary key(physical_id)
);

The second table uses first table auto-generated value as its value. I am not sure how to model this in hibernate.

I read http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html#mapping-declaration-onetoone, but I doesn't seem to understand.

A: 

It's actually hard to say, I don't know what you want to represent at the object level: is it a one-to-one foreign key association? a many-to-one association? is the association bi-directional? Using an ORM means thinking objects more than tables and it usually help to provide the object model.

I'll assume this is a one-to-one foreign key association. Here is what Java Persistence with Hibernate recommends:

7.1.2 One-to-one foreign key associations

Instead of sharing a primary key, two rows can have a foreign key relationship. One table has a foreign key column that references the primary key of the associated table. (The source and target of this foreign key constraint can even be the same table: This is called a self-referencing relationship.)

Let’s change the mapping from a User to an Address. Instead of the shared primary key, you now add a SHIPPING_ADDRESS_ID column in the USERS table:

<class name="User" table="USERS">
  <many-to-one name="shippingAddress"
               class="Address"
               column="SHIPPING_ADDRESS_ID"
               cascade="save-update"
               unique="true"/>
</class>

The mapping element in XML for this association is <many-to-one> — not <one-to-one>, as you might have expected. The reason is simple: You don’t care what’s on the target side of the association, so you can treat it like a to-one association without the many part. All you want is to express “This entity has a property that is a reference to an instance of another entity” and use a foreign key field to represent that relationship. The database schema for this mapping is shown in figure 7.3.

alt text

Figure 7.3 A one-to-one foreign key association between USERS and ADDRESS

An additional constraint enforces this relationship as a real one to one. By making the SHIPPING_ADDRESS_ID column unique, you declare that a particular address can be referenced by at most one user, as a shipping address. This isn’t as strong as the guarantee from a shared primary key association, which allows a particular address to be referenced by at most one user, period. With several foreign key columns (let’s say you also have unique HOME_ADDRESS_ID and BILLING_ADDRESS_ID), you can reference the same address target row several times. But in any case, two users can’t share the same address for the same purpose.

Let’s make the association from User to Address bidirectional.

Inverse property reference

The last foreign key association was mapped from User to Address with <many-to-one> and a unique constraint to guarantee the desired multiplicity. What mapping element can you add on the Address side to make this association bidirectional, so that access from Address to User is possible in the Java domain model?

In XML, you create a <one-to-one> mapping with a property reference attribute:

<one-to-one name="user"
            class="User"
            property-ref="shippingAddress"/>

You tell Hibernate that the user property of the Address class is the inverse of a property on the other side of the association. You can now call anAddress.getUser() to access the user who’s shipping address you’ve given. There is no additional column or foreign key constraint; Hibernate manages this pointer for you.

If what you have is actually a real many-to-one association, it should be pretty easy to adapt the above solution.

Pascal Thivent