Multiple fetch em duas bags

2 respostas
bruno.costa

Pessoal, estou precisando recuperar um tanto razoável de informações para processar, recupero as informações em forma de ScrollableResults

Uma parte da Classe Contrato

@Entity
@Audited
@SequenceGenerator(name = "seq_contratoVendas", sequenceName = "s_contratoVendas", initialValue = 1)
public class Contrato implements Identifiable {

	@Id
	@GeneratedValue(generator = "seq_contratoVendas")
	private Long id;

	@OneToMany(mappedBy = "contrato")
	private List<Beneficiario> beneficiarios;

	@OneToMany(mappedBy = "contrato")
	private List<ProdutoProposta> produtos;
}

Preciso de uma query que faça fetch nas duas listas.

Criteria criteriaContrato = this.session.createCriteria(Contrato.class, "c");

		Criteria tipoContratacao = criteriaContrato.createCriteria("c.planoSaude");
		tipoContratacao.add(Restrictions.eq("tipoContratacao.id", TipoContratacao.INDIVIDUAL_FAMILIAR));

		DetachedCriteria notExistsTitulos = DetachedCriteria.forClass(TituloFinanceiroReceita.class, "t");
		notExistsTitulos.setProjection(Projections.id());

		notExistsTitulos.add(Restrictions.eqProperty("c.id", "t.contrato.id"));
		notExistsTitulos.add(Restrictions.ge("t.vencimento", remessa.getDataInicial()));
		notExistsTitulos.add(Restrictions.le("t.vencimento", remessa.getDataFinal()));

		criteriaContrato.add(Subqueries.notExists(notExistsTitulos));

		Conjunction conjunction = Restrictions.conjunction();

		conjunction.add(Restrictions.ge("c.diaVencimento", remessa.getDataInicial().getDayOfMonth()));
		conjunction.add(Restrictions.le("c.diaVencimento", remessa.getDataFinal().getDayOfMonth()));
		conjunction.add(Restrictions.eq("c.statusContratoVenda", StatusContratoVenda.ATIVO));

		if (remessa.getNumeroContrato() != null) {
			conjunction.add(Restrictions.eq("c.numeroContrato", remessa.getNumeroContrato()));
		}

		if (remessa.getBanco() != null && remessa.getBanco().getId() != null) {
			conjunction.add(Restrictions.eq("c.banco", remessa.getBanco()));
		}

		criteriaContrato.add(conjunction);
		criteriaContrato.setFetchMode("beneficiarios", FetchMode.JOIN);
		criteriaContrato.setFetchMode("produtos", FetchMode.JOIN);

		criteriaContrato.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

		return criteriaContrato.setCacheable(false).setReadOnly(true).setFetchSize(5000).scroll(ScrollMode.FORWARD_ONLY);

porém recebo o org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

Lendo a documentação vi que isso é possível utilizando uma anotação @IndexColumn, ficando assim

@Entity
@Audited
@SequenceGenerator(name = "seq_contratoVendas", sequenceName = "s_contratoVendas", initialValue = 1)
public class Contrato implements Identifiable {

	@Id
	@GeneratedValue(generator = "seq_contratoVendas")
	private Long id;

	@OneToMany(mappedBy = "contrato")
        @IndexColumn(name="benef_index" base=0)
	private List<Beneficiario> beneficiarios;

	@OneToMany(mappedBy = "contrato")
        @IndexColumn(name="prod_index" base=0)
	private List<ProdutoProposta> produtos;
}

Executa a query, nos testes eu possuo 2 beneficiários no contrato, mas dessa forma ele traz somente 1.

Alguma luz? ou teria uma forma melhor de fazer isso.

2 Respostas

bruno.costa

Putz…

Se eu executar criteria.list(); ele faz tudo certo!!! porém usando ScrollableResults vem zoado… :shock:

tiago.vt

tive esse mesmo problema usando jpql quando uso 2 eager na anotação pesquisando sobre o assunto encontrei que seria um bug do jpa…
se vc usar jpl vc pode trabalha com join.

Criado 22 de novembro de 2011
Ultima resposta 22 de nov. de 2011
Respostas 2
Participantes 2