Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it recommended to avoid unidirectional one-to-many association on a foreign key? [duplicate]

Possible Duplicate:
Hibernate unidirectional one to many association - why is a join table better?

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.

like image 763
Shaw Avatar asked Jan 19 '10 10:01

Shaw


People also ask

Why would anyone want to use a join table in a unidirectional one to many association?

Hibernate creates a Join Table for a unidirectional OneToMany because by implementation, the foreign key is always kept at the many side. So in your example, the foreign key will be kept at the Flight table side AND thus to prevent having null values at the Many side Hibernate chooses to create a JoinTable.

What is the difference between one to many and many-to-one?

The difference between One-to-many , Many-to-one and Many-to-Many is: One-to-many vs Many-to-one is a matter of perspective. Unidirectional vs Bidirectional will not affect the mapping but will make difference on how you can access your data. In Many-to-one the many side will keep reference of the one side.

What is the default mechanism for representing one to many unidirectional relationships in JPA?

Unidirectional @OneToMany with @JoinColumn.

How do you map one to many?

One To Many Mapping in Hibernate. In simple terms, one to many mapping means that one row in a table can be mapped to multiple rows in another table. For example, think of a Cart system where we have another table for Items. A cart can have multiple items, so here we have one to many mapping.


1 Answers

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 @CalmStorm's deleted answer 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.

like image 121
APC Avatar answered Oct 27 '22 00:10

APC