views:

170

answers:

2

In the Hibernate online documentation, under section 7.2.3 One-to-many, it's mentioned, that:

unidirectional one-to-many association on a foreign key is an unusual case, and is not recommended. You should instead use a join table for this kind of association.

I would like to know why? The only thing that comes to my mind is, it can create problems during cascade deletes. For example, Person refers to address on a one to many relationship on a foreign key, and the address would refuse to be deleted before the person.

Can anyone explain the rational behind the recommendation?

Here is the link to the reference document content: 7.2.3. One-to-many

I have copy pasted the actual content here:

A unidirectional one-to-many association on a foreign key is an unusual case, and is not recommended.

    <class name="Person">
        <id name="id" column="personId">
            <generator class="native"/>
        </id>
        <set name="addresses">
            <key column="personId" 
                not-null="true"/>
            <one-to-many class="Address"/>
        </set> </class>

    <class name="Address">
        <id name="id" column="addressId">
            <generator class="native"/>
        </id> </class>

create table Person ( personId bigint not null primary key )
create table Address ( addressId bigint not null primary key, personId bigint not null )


You should instead use a join table for this kind of association. 
+2  A: 

The following hibernate posting discusses this in great detail. https://forum.hibernate.org/viewtopic.php?t=957582&amp;start=0&amp;postdays=0&amp;postorder=asc

Calm Storm
Thanks. It was helpful. I'm still not sure if a clean model, and being right justifies it.
Shaw
+1  A: 

unidirectional one-to-many association on a foreign key is an unusual case, and is not recommended.

There are two aspects to this:

  • unidirectional
  • one-to-many

The thread Calm Storm links to addresses only the second of these things, but let's start with it.

That thread recommends replacing one-to-many relationships with join tables because otherwise the one-to-many approach 'populates the many side table with columns that don't belong to that entity, are there only for "linking" porpuses (sic)'. This tactic may result in a clean model in the Hibernate layer but unfortunately it results in a broken database.

Because SQL can only assert that the child record has a parent; there is no way to enforce a rule that the parent must have a child. Consequently there is no way to insist that a table have entries in a join table, the upshot being that it becomes possible to have orphaned child records, the very thing that foreign keys are intended to prevent.

I have several other objections, but the next most important one is inappropriateness. Intersection tables are meant to represent many-to-many relationships. Using them to represent one-to-many relationships is confusing and requires too many additional database objects for my liking.

So, to the second aspect: unidirectional one-to-many associations. The problem with these is the peculiar fashion in which Hibernate handles them by default. If we insert a parent and a child in the same transaction, Hibernate inserts the child record, then it inserts the parent, then it updates the child with the parent's key. This requires deferrable foreign key constraints (yuck!) and probably deferrable not null constraints as well (double yuck).

There are a couple of workarounds to this. One is to use birectional one-to-many associations. According to in the document you cite this is the most common approach. The other approach is to tweak the mapping of the child object but that has its own ramifications.

APC
Thanks, that clarifies a lot!
Shaw