Monday, September 3, 2007

Hibernate: Annotation one-to-many (foreign-key)

Hibernate Doc (Chap 8.2.3)

::Relationship::
person(one) -> address(many)

::DB Schema::
person( personId )
address( addressId, personId )

::Java Operation::
person.getAddresses();

::Annotation::
@Entity
@Table(name="PERSON")
public class Person {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="personId")
private int id;

@OneToMany
@JoinColumn(name="personId") 
private Set <Address> addresses;
}

@Entity
@Table(name = "ADDRESS")
public class Address {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "addressId")
private int id;
}

::Generated SQL (mysql5.0)::
[Association Mapping List]

7 comments:

Greg said...

This page is called one-to-many (foreign-key) but I don't see a foreign key anywhere.

I believe the address table should have a foreign key called personID. I think the line '@Column(name="personId")' in the Person class actually points to the personID foreign key in the address table.

Is this right?

Tim said...

thanks, this helped me figure out how to achieve this. hibernate's documentation says this kind of mapping is unusal but i disagree.

@greg, the
@JoinColumn(name="personId")
on the addresses Set is what defines the fk column in the addresses table. @JoinColumn is also what tells hibernate to use a fk column as opposed to a separate table, which i tend to think is more common with many-to-many associations.

jpongin said...

I believe the foreign key is implied in the schema.

Vic said...

it does not work with toplink (Build 060830)

@OneToMany for attribute name [addresses] in entity class [class org.simple.jpa.core.schema.model.relationships.Person] 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.

atomic said...

Tadaya-san,

Your blog posts here were very helpful in solving a strange annotation mapping problem i was having!

Domo arigato gozaimasu! :)

shafeer v c said...

I used one-many relation for a table having one record(parent table) which refers to a table(having forein key ) and has two records corresponding to my primary key relation..
Problem is when I fetch the records of parent table the size of the record shown is 2. But I expect to have only size one since my parent table has only one record.
Can any one help me out of this issue?

Pascal Thivent said...

@Vic Actually, the above solution is Hibernate specific, this is not part of JPA 1.0.

Using a JoinColumn on a OneToMany is not allowed by JPA 1.0. JPA 1.0 does not support unidirectional OneToMany without a JoinTable.

It is possible in JPA 2.0 though.

See the following sections of the JPA 1.0 specification:

- 9.1.6 JoinColumn Annotation
- 2.1.8.5.1 Unidirectional OneToMany Relationships