Hi, sorry if you guys don’t consider this question as a Hibernate question, but I asked in JSF forum and people said: “this isn’t a JSF question”.
I’m using JSF and CDI Transactional with Hibernate. My problem is:
I created a method where I initialize my entity and the lazy collections:
public void initializePessoa() {
pessoa = getEntityManager().createQuery(
"SELECT p FROM Pessoa p " +
"LEFT JOIN FETCH p.enderecos e " +
"LEFT JOIN FETCH e.tipo " +
"WHERE p.empresa.id = :empresaId " +
"AND p.empresaCodigo = :empresaCodigo", Pessoa.class)
.setParameter("empresaCodigo", idParameter)
.setParameter("empresaId", loginController.getEmpresa().getId())
.getSingleResult();
pessoa.setEmails(getEntityManager().createQuery(
"SELECT pe FROM PessoaEmail pe " +
"JOIN FETCH pe.tipo " +
"WHERE pe.pessoa.id = :pessoaId", PessoaEmail.class)
.setParameter("pessoaId", pessoa.getId())
.getResultList());
}
So I edit the Pessoa entity and I use a method with @Transactional to merge, but in my business view user could save and stay in the view to change again, so if I don’t initialize objects again after merge() everything is detached.
But if I use initializePessoa() inside the method with @Transactional, like this:
I get the error: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance when I try to set a Lazy Collection again.
So is there any suggestion when and how I could refetch objects after merge()?
Because if I edit Person edit and hit button save, I merged the Person. If I just hit button save again, without initialize Collections again, I got LazyInitiationException.
I didn’t understand, what do you mean traverse? Use the getter?
You get the LazyInitializationException because you didn’t fetch the collection after merge. Also, merge is not like save. It’s for merging detached entities.
Traversing means accessing the collection and maybe read its size.
Yes, that’s what I’m trying to do, fetch collections after merge. And about merge if I understand what you’re saying this isn’t a situation that I should use merge() ?
Now I understand.
Do you have any example what I should do?
Let me try to explain showing what’s going on:
I start the view editing a Pessoa and fetch the Lazy Collections that I need using initializePessoa().
I edit something and hit save button, before the merge my obj is this:
After merge the obj turns like this:
I read that is the normal behavior. So I need to fetch and initialize my Pessoa again, because if I didn’t, on the first pessoa.getEnderecos(), I get LazyInitiationException.
But if I use initializePessoa() or even if I use pessoa.setLazyListX(), inside the method with @Transactional CDI, I get A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance.
So what I’m doing wrong, it’s the way that I’m refetching my objects and which is the right way? Or I should not use merge() like this?
After all size(), the obj continue like the second screenshot that I’ve sent before and at the first use of any collection I get LazyInitializationException.