albfan
albfan

Reputation: 12940

Is @OneToMany annotation useful?

Using such annotation in a pet project seems to work great, I'm a boss and have two Employees, etc. But in real scale projects you end with an Accounting year related with 100.000 invoces or a City with 1.000.000 citizens and naively try to retrieve all of them in an ArrayList leads to OutOfMemory errors.

A good approach is to not define such relation (But the @ManyToOne) and retrieve paginated those results to do whatever you want with them.

So, ¿Is there any Observer pattern or similar to deal with a big database model? ¿Any configuration you can use to manage memory?

Upvotes: 5

Views: 618

Answers (4)

Dragan Bozanovic
Dragan Bozanovic

Reputation: 23552

As other answers already explained, it is a bad idea to have a full-functioning @OneToMany association in such extreme cases.

However, a case in which such an association could still be handy is in JPQL/HQL queries, as you would be able to use path navigations from the parent entity. To make sure that the collection is not accessed, you can just provide the mappings on the collection's private field without exposing getter and setter for it (and leave the association lazy, of course).

Upvotes: 0

Jeroen van Dijk-Jun
Jeroen van Dijk-Jun

Reputation: 1038

In some OneToMany relations the amount of objects related could become too big, but there are many real life examples where this is not the case. If you would make a Scrum Team object with Scrum Team Members, ideally this amount would be 3-9 objects. That's very little, and the OneToMany is extremely useful.

But the point you make is valid: if there is too much data, at least have it lazy loaded, and even then the amount of records could become too large. If that is the case, I can imagine the OneToMany is not handy at all. In this case I would turn to Spring Data, having a querymethod which can give me that too big list in pages. Then indeed I would remove the OneToMany as I will never use it again.

Some side note: I always make the other side: ManyToOne, so I can use mappedBy and have my database creating better tables with a foreign key, instead of a new table in between. This helps often a little bit with performance, and in some way I got the feeling that you can now load a few more objects in one call. But... if there are too many records to load, you don't want to get in this danger zone, so I then still remove that OneToMany.

Upvotes: 0

Arnold Galovics
Arnold Galovics

Reputation: 3416

Let's say you have an application which shows all the citizen data for a specific City. This City has 1.000.000 citizens in it, so you want to show this many rows on the user-interface.

Do you think it makes sense to show this much data at once or do you think pagination is necessary? I'd say the latter is the case because noone will read through 1 million records on the UI.

Just to suggest something, if you have this much data, don't use entities to show the information on the UI. Use projections instead which contains the exact data you need to show + you can easily introduce pagination as well.

There are ways to define projections, the easiest one is to use Spring Data JPA's feature which is basically defining interfaces.

Of course, if you have a job which have to process all citizens, then also it's not a good idea to fetch everything at once but to do some kind of batch execution. Split your data into separate parts, then deal with those parts. In this case, it's also a good idea to use projections.

Upvotes: 1

Sasha Shpota
Sasha Shpota

Reputation: 10300

Well, this is the question of the application architecture. I can't imagine the business value of getting 1 million users by their city, but I can imagine the case when I need to get city by user or pets by their owner.

So @ManyToOne is not an anti-pattern as long as ORM is used with understanding of its consequences.

You as a developer or application architect must know your domain best then everyone else and you should know when a solution fits well or not.

Upvotes: 0

Related Questions