Hibernate/JPA ManyToOne vs OneToMany

HibernateJakarta EeJpaOne to-ManyMany to-One

Hibernate Problem Overview


I am reading currently the documentation of Hibernate regarding the entity associations and I come accross a little difficulty to figure out some things. It has to do in essence with the difference between ManyToOne and OneToMany associations. Although I have used them in real projects, I cannot comprehend completely the difference between them. To my understanding, if a table / an entity has a ManyToOne association with another, then the association should be from the other side OneToMany. So, how should we decide which one to choose based on a specific case and how does it affect the database/queries/results? Is there everywhere a good example?

P.S.: I reckon it would be helpful due to its relevance to the question, if someone could besides explain what is the point of the owner of the association and the difference between Bidirectional and Unidirectional association.

Hibernate Solutions


Solution 1 - Hibernate

Suppose you have an Order and an OrderLine. You can choose to have a unidirectional OneToMany between Order and OrderLine (Order would have a collection of OrderLines). Or you can choose to have a ManyToOne association between OrderLine and Order (OrderLine would have a reference to its Order). Or you can choose to have both, in which case the association becomes a bidirectional OneToMany/ManyToOne association.

The solution you choose mainly depends on the situation, and on the level of coupling between the entities. For example, if a user, a company, a provider all have many addresses, it would make sense to have a unidirectional between every of them and Address, and have Address not know about their owner.

Suppose you have a User and a Message, where a user can have thousands of messages, it could make sense to model it only as a ManyToOne from Message to User, because you'll rarely ask for all the messages of a user anyway. The association could be made bidirectional only to help with queries though, since JPQL queries join between entities by navigating through their associations.

In a bidirectional association, you could be in a situation where the graph of objects is inconsistent. For example, Order A would have an empty set of OrderLines, but some OrderLines would have a reference to the Order A. JPA imposes to always have one side of the association being the owner side, and the other side being the inverse side. The inverse side is ignored by JPA. The owner side is the side that decides what relation exists. In a OneToMany bidirectional association, the owner side must be the many side. So, in the previous example, the owner side would be OrderLine, and JPA would persist the association between the lines and the order A, since the lines have a reference to A.

Such an association would be mapped like this:

in Order :

@OneToMany(mappedBy = "parentOrder") // mappedBy indicates that this side is the 
   // inverse side, and that the mapping is defined by the attribute parentOrder 
   // at the other side of the association.
private Set<OrderLine> lines;

in OrderLine :

@ManyToOne
private Order parentOrder;

Solution 2 - Hibernate

Also, having @ManytoOne side as the owner would require only n+1 queries while saving the associtions. Where n is the number of associations (many side).

Whereas having @OneToMany as the owner, while inserting the parent entity (one side) with associations (many side) would result in 2*N + 1 queries. In which one query would be for insert of the association and other query would be for updating foreign key in the associated entity.

Solution 3 - Hibernate

While above answers are accurate, I will present the answer in a different way.

Both @OneToMany and @ManyToOne have two parts; left part and right part. For example:

  • @OneToMany = 'One' is left part and 'Many' is right part
  • @ManyToOne = 'Many' is left part and 'One' is right part

Simple rule of association using this understanding is, left part represents the class in which you are defining the association.

So, if you define @ManyToOne in OrderLine class referencing to Order class, it means many OrderLine associated to one Order class.

Solution 4 - Hibernate

I will answer by an example. Suppose you have a design for an Ordering or a POS system. Then, each order has order details (e.g. products). In that case we have a @oneToMany relationship. The same will apply for a sale and sale details relationship.

If I have a user table and each user is tied to a specific shop then we can have many users tied to the same shop hence @manyToOne.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionarjacsohView Question on Stackoverflow
Solution 1 - HibernateJB NizetView Answer on Stackoverflow
Solution 2 - HibernateuserJView Answer on Stackoverflow
Solution 3 - HibernateGigi MathewView Answer on Stackoverflow
Solution 4 - HibernateZadiki Hassan OcholaView Answer on Stackoverflow