persistence@glassfish.java.net

Re: Uni-directional OneToMany entity mapping

From: Martin Bayly <mbayly_at_telus.net>
Date: Thu, 11 Jan 2007 13:29:05 -0800

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!
>