persistence@glassfish.java.net

Re: Uni-directional OneToMany entity mapping

From: Wonseok Kim <guruwons_at_gmail.com>
Date: Fri, 12 Jan 2007 10:57:20 +0900

Hi Martin,

I could confirm the following example in "*Enterprise JavaBeans 3.0, 5th
Edition (Bill Burke)" ch7(p.130)
*

@Entity
public class Customer implements java.io.Serializable {
    ...
    private Collection<Phone> phoneNumbers = new ArrayList<Phone>( );
    ...
    @OneToMany(cascade={CascadeType.ALL})
    @JoinColumn(name="CUSTOMER_ID")
    public *Collection<Phone>* getPhoneNumbers( ) {
       return phoneNumbers;
    }
    public void setPhoneNumbers(Collection<Phone> phones) {
        this.phoneNumbers = phones;
    }
}

The book shows two examples using both join column and join table, and
Hibernate seem to support the join column mode as well. People who see this
book(or Hibernate users) will think they can use join column for
uni-directional one-to-many.

I think it is a good idea to support this way in TopLink even if it's not
portable and not recommended.
Could you file an enhancement issue for this?

Thanks,
-Wonseok

On 1/12/07, Martin Bayly <mbayly_at_telus.net> wrote:
>
> Thanks for the reply - I didn't have a specific pressing need to make it
> uni-directional - it just seemed superfluous and was showing up in
> default reflection based toString implementations (e.g. using
> org.apache.commons.lang.builder.ToStringBuilder) so I figured I'd remove
> it - but then ran into trouble making it uni-directional.
>
> I'll just leave it bi-directional.
>
> Thanks
> Martin
>
> Craig L Russell wrote:
> > Hi Martin,
> >
> > The portable way of mapping this in Java Persistence is to have a
> > relationship from TelephoneNumber to Customer. It's easier for the
> > persistence provider to manage the relationship if it's bidirectional.
> > The reason it's easier is just because of implementations. I agree
> > that from the user perspective it's easier to use either uni- or
> > bi-directional relationships, but the spec was a compromise.
> >
> > What is your concern with the bidirectional relationship? If it's just
> > a modeling issue, you can always make the relationship to Customer
> > private (field) or protected (field or property).
> >
> > Craig
> >
> > On Jan 11, 2007, at 12:21 PM, Martin Bayly wrote:
> >
> >> 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
> >
> > Craig Russell
> > Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
> > 408 276-5638 mailto:Craig.Russell_at_sun.com
> > P.S. A good JDO? O, Gasp!
> >
>