persistence@glassfish.java.net

Uni-directional OneToMany entity mapping

From: Martin Bayly <mbayly_at_telus.net>
Date: Thu, 11 Jan 2007 12:21:01 -0800

I was trying to setup a uni-directional OneToMany mapping.

An example of this mapping might be a customer's telephone numbers.

e.g.
CUSTOMER
id
name

TELEPHONE_NUMBER
id
number
cust_id (FK->CUSTOMER.id)

In my entities I tried setting this up by adding a collection of
TelephoneNumbers to my Customer entity and annotating it with a
@OneToMany. The TelephoneNumber entity has no reference to the Customer
entity.

e.g. in Customer

@OneToMany
 public List<TelephoneNumber> getTelephoneNumbers() {
        return this.telephoneNumbers;
 }

However, this creates a join table instead which is not what I wanted.

I tried adding an @JoinColumn(name="cust_id") annotation to the
getTelephoneNumbers but TopLink complains that @JoinColumn is not valid.

[TOPLINK-7160] (Oracle TopLink Essentials - 9.1 (Build b26)):
oracle.toplink.essentials.exceptions.ValidationException
Exception Description: @OneToMany for attribute name [telephoneNumbers]
in entity class [class com.domain.Customer] should not have
@JoinColumn(s) specified. In the case where the @OneToMany is not mapped
by another entity (that is, it is the owning side and is
uni-directional), it should specify (optional through defaulting) a
@JoinTable.

I'm not following this. It used to work when the relationship was
bi-directional i.e. the TelephoneNumber had a reference to it's customer
and I used @OneToMany(mappedBy="customer"). However, I don't want that
additional reference.

The book "Enterprise JavaBeans 3.0, 5th Edition" seems to indicate that
the correct way to do a OneToMany uni-directional without join table is
using @OneToMany and @JoinColumn.

Also the Hibernate Entity Manager reference manual indicates this is
also possible but has the following caveat that I don't really understand:
"A unidirectional one to many using a foreign key column in the owned
entity is not that common and not really recommended."

So what's the deal here - it seems like this is a really normal thing to
try and do. Using a FK column on the owned entity seems like the
standard way to model a OneToMany relationship in a relational db - I
don't see why the relationship should have to be bi-directional in JPA
terms to achieve this modeling? What am I missing here? Why does the
Hibernate manual say it's not recommended?

Thanks for any insight.
Martin Bayly