JPA / Hibernate - Lazyloading Onetomany duplicating records

Asked

Viewed 431 times

1

Well, I have the following structure:

public class FinCxaTransacaoGrupo {

    @Id
    @GeneratedValue(generator="gen-uuid")
    @GenericGenerator(name="gen-uuid", strategy = "uuid2")
    @Type(type="pg-uuid")
    @Column(name="id_fin_cxa_transacao_grupo")
    private UUID idFinCxaTransacaoGrupo;

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="id_fin_cxa_transacao_destino")
    private FinCxaTransacao finCxaTransacaoDestino;

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="id_fin_cxa_transacao_origem")
    private FinCxaTransacao finCxaTransacaoOrigem;

}

public class FinCxaTransacao {

    @Id
    @GeneratedValue(generator = "gen-uuid")
    @GenericGenerator(name = "gen-uuid", strategy = "uuid2")
    @Type(type = "pg-uuid")
    @Column(name = "id_fin_cxa_transacao")
    private UUID idFinCxaTransacao;

    @OneToMany(cascade=CascadeType.ALL, mappedBy = "finCxaTransacao")
    private List<FinCxaPlanoLcto> finCxaPlanoLctos = new ArrayList<>();

    @OneToMany(mappedBy="finCxaTransacaoDestino")
    private List<FinCxaTransacaoGrupo> finCxaTransacaoGruposDestino = new ArrayList<>();

    @OneToMany(mappedBy="finCxaTransacaoOrigem")
    private List<FinCxaTransacaoGrupo> finCxaTransacaoGruposOrigem = new ArrayList<>();

}

public class FinCxaPlanoLcto {

    @Id
    @GeneratedValue(generator="gen-uuid")
    @GenericGenerator(name="gen-uuid", strategy = "uuid2")
    @Type(type="pg-uuid")
    @Column(name="id_fin_cxa_plano_lcto")
    private UUID idFinCxaPlanoLcto;

    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    @JoinColumn(name="id_fin_cxa_transacao")
    private FinCxaTransacao finCxaTransacao;

}

Query executed to find the Group:

public FinCxaTransacaoGrupo buscarFinCxaTransacaoGrupoEstorno(UUID idFinCxaTransacao) {

    CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
    CriteriaQuery<FinCxaTransacaoGrupo> query = cb.createQuery(FinCxaTransacaoGrupo.class);
    Root<FinCxaTransacaoGrupo> finCxaTransacaoGrupo = query.from(FinCxaTransacaoGrupo.class);
    query.where(cb.or(cb.equal(finCxaTransacaoGrupo.get(FinCxaTransacaoGrupo_.finCxaTransacaoDestino).get(
            FinCxaTransacao_.idFinCxaTransacao), idFinCxaTransacao),
            cb.equal(finCxaTransacaoGrupo.get(FinCxaTransacaoGrupo_.finCxaTransacaoOrigem).get(
                    FinCxaTransacao_.idFinCxaTransacao), idFinCxaTransacao)));

    query.distinct(true);

    query.select(finCxaTransacaoGrupo).distinct(true);
    return em.createQuery(query).getSingleResult();
}

The Fincxatransacaogroup table contains a record. The Fincxatransacao table contains a record for finCxaTransacaoDestino and finCxaTransacaOrigem;

the Fincxaplanolcto table contains two records for finCxaTransacaoDestino and one record for finCxaTransacaoOrigem;

Remembering that in the structure, the Fincxaplanolcto is Lazyloading... When searching finCxaTransacaoDestino.getFinCxaPlanoLctos() this list returns with duplicate records, that is, the return is 4 items and the database contains only two, being a duplication for each record.

However, in the finCxaTransacaoOrigem.getFinCxaPlanoLctos() object that contains only one record in the database, this list returns only one record, without duplications...

I searched several examples where the staff solves using Set instead of List for the Onetomany interface, it solves my problem, but in other situations does not allow me to insert duplicate values when necessary.

I wonder why JPA is duplicating the records and if there is any solution?

  • Cara I’ll give you a suggestion debug, adds a file properties of log4j in the briefcase resources of your project and activates the sql full of Hibernate, to see if you are running two inserts....

1 answer

1


The solution I made for my problem was to convert the list to a Set<> and then add again to the List and return it. Yes and consider a gambiarra, as soon as possible I will perform the suggestion passed and use the log4j.

Grateful.

Set finCxaPlanoLctos = new Hashset<>(finCxaTransacaoGrupoReturn.getFinCxaTransacaoDestino().getFinCxaPlanoLctos()); finCxaTransacaoGroupoReturn.getFinCxaTransacaoDestino(). getFinCxaPlanoLctos(). clear(); finCxaTransacaGroupoReturn.getFinCxaTransacaoDestino(). getFinCxaPlanoLctos(). addAll(finCxaPlanoLctos);

Browser other questions tagged

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