Peter Goodheart
Peter Goodheart

Reputation: 369

Hibernate, OneToOne single foreign key references

My database skills are a little rusty, so it's a little harder for me to learn Hibernate.

I have been reading up on one-to-one, one-to-many and many to many and in a nutshell, this is what I understand from my youth:

One-To-One: - Table A is linked to another row in Table B, and the number of rows in Table A must equal the number of rows in Table B.

One-To-Many: - each company can have many employees.

Many-To-Many: - many doctors can have / share various patients. (no pun intended).

Let's say I have the following tables, for an undertaker client model

Table Person:

[ id[pk], fullname(char), age(int), address(char), sendFlowers(boolean), country_id[fk], whenDead_id[fk] ]

1, 'Martin Jensen', 91, 'Notlucky Street 4', false, 2, 1

2, 'Killer Klaus', 67, 'Die-Hard Strasse 9', true, 1, 2

2, 'Bingo Man', 46, 'Secret Address', true, 1, 2

Table: Country

[id[pk], name(char)]


1, 'Germany'

2, 'North Korea'

Table: WhenDead


[ id[pk], actionToTake(char) ]

1, 'Ignore / Impossible pickup'

2, 'Cremate / Imitate relative and collect insurance'

Under normal circumstances, I would just use a join, to the two foreign keys, using plain SQL, if I needed some information from those tables. (fx the description, and not just the id). Each person can only be connected to ONE country and ONE WhenDead table, however, multiple persons should be able to refer to the same foreign key values of course, in order to avoid duplication.

I tried to use the @OneToOne annotation in Hibernate, with the column name of both these tables as a foreign key id on the Entity. It works, however, it seems to go against what OneToOne stands for... "that each row in a table has a corresponding row in another table" and "the number of rows, must match in both tables".

Using One-To-Many or Many-To-Many seems unnatural.

Can someone push me in the right direction, or should I just continue with the OneToOne, which every indian hibernate tutorial says "is never used unless you have a big design flaw"

Upvotes: 0

Views: 385

Answers (1)

JB Nizet
JB Nizet

Reputation: 692121

You got it wrong, and you forgot one kind of association: ManyToOne.

Let's take your example:

  • OneToOne from A to B: an A has 0 or one B, and B can't be associated to several As. The number of rows in both tables is thus not necessarily the same. Example: One car has one one plate number (or 0 if it's not sold yet). OneToOne are indeed quite rare, and I had a hard time finding an example.

  • OneToMany: one A has 0, 1 or several B(s). Example: a company has many employees.

  • ManyToOne: A has 0 or one B, and B can be associated to several As. For example: a person has one father (and a father may have several children).

  • ManyToMany: A has 0, 1 or several Bs, and B can be associated to 0, one or several As. Typical example: a student has many courses, and a course is followed by several students.

So, for your tables/entities, you have the following associations:

  • Person - ManyToOne - Country
  • Person - ManyToOne - WhenDead

Indeed, several persons live in the same country, but a person lives in 0 or 1 country. And several persons might desire to be cremated (not sure that's proper English), but a person can't be both cremated and buried.

Of course you could choose to make these associations bidirectional, or even to only implement them in the other direction. In which case, you would have

  • Country - OneToMany - Person
  • WhenDead - OneToMany - Person

In short, every time you have a foreign key from one table to another, you have a ManyToOne or OneToOne association. If you can put a unique constraint on the foreign key, it's a OneToOne, because there is a guarantee that two rows of the first table can't reference the same row of the target table. Otherwise, it's a ManyToOne.

Upvotes: 1

Related Questions