How to fetch extra OneToMany and set in parent side

Hi,

Based on previous tips that I got here. I’m trying to initialize multiples @OneToMany List and I getting some errors.

I have six @OneToMany Lists in my parent entity. So, I fetch the parent with one of them.
And the rest I’m using Hibernate.initialize(obj);

But one of them I need to fetch and also fetch to initialize sub entities. So if I use Hibernate.initialize on it, this sub entity won’t initialize. So I tried to do this:

pessoa.getObservacoes().clear();
pessoa.getObservacoes().addAll(getEntityManager().createQuery(
      "SELECT po FROM PessoaObservacao po " +
               "JOIN FETCH po.usuario " +
               "WHERE po.pessoa.id = :pessoaId", PessoaObservacao.class)
      .setParameter("pessoaId", pessoa.getId())
      .getResultList());

I found this as a solution in Stack Overflow, but in my method I’m using @Transactional from Java EE 7.

When I run this, addAll() is deleting the data, what’s the correct way to initialize this collection?

Thanks in advance

Clearing the collections and reconstructing it based on a query looks like a hack.

Now, the only time when you need to initialize an association is if you plan on modifying it. Having to initialize 6 collections sounds like you are trying to fetch more than necessary. Do you really need everything initialized because you want to modify the structure?

Anyway, if you don’t need to modify the structure just fetch all the needed collections using queries and populate a DTO with them.

In this case I really need, it’s a JSF form with multiples tabs where the user can edit all of them.

For example, one tab he can edit Address, the other Emails and this one is the Observations, but in Observation I need the User associate with them.

I found this topic in Stack where one of the answers is the exactly same case that I have: https://stackoverflow.com/questions/47574252/hibernate-initialization-of-complex-object

User user = /** Parent with one of the Collections **/
Hibernate.initialize(user.getGrapevines());
user.getGrapevines().forEach(grapevine -> Hibernate.initialize(grapevine.getGrapes()));

But I test and it give me 1 Query to the “Grapevines” and 1 Query per different “Grapes” and it doesn’t sounds good.

Maybe you can change the JSF to load dataon demand upon loading the associated Tab.

Yes, you’re completely right this is the best scenario ever.

But even loading data in the associated Tab, how could I set the Collection in parent Entity? Is using the clear() and addAll()?

The method that will load data in a specific tab won’t have the @Transactional, but when I did this in a @Transactional method, it deletes the data in addAll().

No. Just fetch the collection by running a query without linking it to the parent entity.

Sorry, but just to finish.

In this case you’re suggesting just a @ManyToOne only in child side, like you recommend in this article: https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/

So depending of the situation (based on my view) I should remove the @OneToMany from parent?

Only you can know if you need it or not. My suggestion was to question the need for mapping collections as a mandatory requirement. If you don’t need to propagate changes from parent to children via the collection, then you might do just fine without mapping the collection.