Multiple @Elementcollection in two different classes @Embeddable

Asked

Viewed 131 times

1

I have an entity with two classes Embedded of the same kind and each has a Elementcollection same type, too. Business logic seems to be correct, but I’m experiencing some problems with the lack of knowledge at JPA.

Here come my classes:

@Entity
public class Etapa extends EntidadeBase {

    @Embedded
    private CronogramaDeDesembolso cronogramaDeReceita;

    @Embedded
    private CronogramaDeDesembolso cronogramaDeDespesa;
}

@Embeddable
public class CronogramaDeDesembolso {

    @ElementCollection
    private List<Parcela> parcelas;
}

I’m getting the following error log:

Caused by: org.hibernate.Hibernateexception: Found Shared References to a Collection: nexxus.convenioestadual.dominio.planodework.etapa.Etapa.cronogramaDeceita.parcelas

Does anyone have any idea what might be wrong and how to fix it?

  • 1

    You are probably assigning the same object to cronogramaDeReceita and cronogramaDeDespesa OR parcelas is the same collection in these schedules, even though they are separate instances. Include how you are creating these objects which is easier to help

  • That was exactly the problem. We were assigning the same object to revenue and expense. Thank you very much.

1 answer

1


Hibernate will present this problem when trying to persist more than one entity it manages that share the same instance of a collection.

For example, this scenario will present this problem:

final Parcela parcela01 = ...
final Parcela parcela02 = ...

final List<Parcela> parcelas = Stream.of(parcela01, parcela02).collect(Collectors.toList());

final CronogramaDeDesembolso despesa = ...
despesa.setParcelas(parcelas);

final CronogramaDeDesembolso receita = ...
receita.setParcelas(parcelas);

final Etapa etapa = ...
etapa.setCronogramaDeDespesa(despesa);
etapa.setCronogramaDeReceita(receita);

// fazer o que mais for necessário e atualizar a instância (persist/merge/etc.)
em.persist(etapa);

It is important to note that what should not be the same is the collection, the items in the collection can be the same. The solution in this case is just to have another collection, something like that:

final Parcela parcela01 = ...
final Parcela parcela02 = ...

final List<Parcela> parcelasDespesa = Stream.of(parcela01, parcela02).collect(Collectors.toList());
final List<Parcela> parcelasReceita = Stream.of(parcela01, parcela02).collect(Collectors.toList());

final CronogramaDeDesembolso despesa = ...
despesa.setParcelas(parcelasDespesa);

final CronogramaDeDesembolso receita = ...
receita.setParcelas(parcelasReceita);

final Etapa etapa = ...
etapa.setCronogramaDeDespesa(despesa);
etapa.setCronogramaDeReceita(receita);

Notice that different objects are generated, when we collect the stream. Just having two different collections, but one you receive from the previous one, will also lead to the problem, something like this:

final List<Parcela> parcelasDespesa = Stream.of(parcela01, parcela02).collect(Collectors.toList());
final List<Parcela> parcelasReceita = parcelasDespesa;

There are other scenarios that this also occurs, even if less common, as in applications that process competing for the same collection. In all scenarios, however, the cause is the same, the same collection instance present in different instances managed by preview.

The central point is: don’t match collections between different objects that are or will be managed by Hibernate :)

  • Once again, thank you, @Brunocésar

Browser other questions tagged

You are not signed in. Login or sign up in order to post.