简体   繁体   中英

JPA and how to think about relationships

I am learning JPA relationships (@OneToOne, @ManyToOne, ...) and as I talk to people about how they model their entities, the more confused I am getting. Here's an example from yesterday:

Lets say we have a relationship between a Person and an Address . The DB stores the Address.id as a FK in the Person s table as "address_id". Is this relationship a OneToOne or a OneToMany? I've heard people argue for each and both have good reasons as to why they feel that way.

One individual argued that it "is a ManyToOne since the address_id is not unique for each record. The same address_id could be used over and over again in the Person s table. He argues that to truly have a OneToOne, the FK in the Person s table would have to be unique as directed in the JSR spec".

Another individual states that "when you think about a Person record, will they have more than one Address ? If not, then it's OneToOne; Why complicate the matter"

I am confused as to which is true. On one hand, the first person was able to bring up the JSR spec and talk me through it. On the other hand, I have a developer with over 20 years experience (and is highly respected) telling me to keep it simple.

Can someone please help clarify this for me

Thank you!

I'll take about the association from Person to Address.

A given person can't have more than one address, since its associated table has a foreign key column to the address.

So, it can be a OneToOne or a ManyToOne.

It's up to you to decide which one it is, and the choice doesn't depend on anything technical. If you don't want two different persons to ever share the same address, then it's a OneToOne. If you decide that two persons can share the same address, then it's a ManyToOne.

If it's a OneToOne, you should make sure that it's indeed a OneToOne, and that two persons can't share the same address. The most effective and simple way to do that is to add a unique constraint of the address_id column of the person table. But Hibernate doesn't care if you set that constraint or not.

Your "other individual" is wrong. If two persons can share the same address, then it should be a ManyToOne. Not a OneToOne. Imagine you make it a bidirectional association: since an address can be shared by several persons, you would have a OneToMany association between Address and Person, which would be the inverse of the association between Person and Address. And a OneToMany's inverse association must be a ManyToOne, not a OneToOne.

We have Person and Address . We need to identify the relationship between them. You could see the relationship in two different ways as below

  1. From Person to Address
  2. From Address to Person

1.From Person to Address

Take an Address instance or row from your table and ask yourself can this particular address row be in a relationship with multiple persons. If yes the Person Side is Many if no Person side is one. So at this stage you have identified whether person is Many or One

Now pick up a person instance or row from your table and ask yourself can this particular person have more than one address . If yes Address side of the relationship is Many else address side is One.

Your Example

Person has a foreign key which references to id of Address

Based on this info Lets brainstorm

Can one Person has more than one related Address??? Each person in the person table has a foreign key(address_id) referencing to the Address row. Given that address_id is not multivalued we can say that one Person can have only one Address related to it. So Address side of the relationship is ONE

Can One Address belong to more than one person ??

As we know person has address_id which is foreign key to Address. And there is no constraint specifying that address_id is unique. That is address_id column can have same value for multiple rows on Person table .Hence we can say that multiple person can have same address. So Person side of the relationship is MANY

At last we conclude that Relationship from PERSON-TO-ADDRESS is MANY-TO-ONE

Note :- if the foreign key address_id in person table has a unique constraint applied to it , in that case multiple person wont be able to refer to same address, hence making the Person side of the relationship ONE. Thus the relationship would have became One-To-One

Some DB doesn't have direct options to set one-to-one relationships. You can force it using unique constraint as says @JB Nizet or using Person.id as the primary key for Adress table and also a foreign key to Person table.

If you don't do this, you won't be able to ensure that a relationship is 1:1 or 1:n without knowing the data values you are working with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM