Tenho como refatorar esse metodo?

2 respostas
jpahibernatespring-boot
thimor

Ola,
Eu estou usando spring-data jpa e tenho esse metodo. Eu uso uma classe ProdutoFilter que tem todos os parametros de pesquisa, e montei a query de forma nativa. Gostaria de saber se tem como refatorar esse metodo, para que o framework entenda que os parametros da query sao para retirar de ProdutoFilter ao inves de ter que passa-los um a um no metodo. Fica muito feio. Eu tentei usar uma outra abordagem que achei que melhor, porem nao funcionou como esperado.
O metodo é esse:

@Query(value = "select p.idproduto as idproduto, p.ean as ean, "
+ "p.descricao as descricao, p.unidsaida as unidade,"
		+ " p.embsaida as embalagem, pp.custozero as precoCusto,pp.margem as margemLucro,pp.venda1 as precoVenda,"
		+ " substring(p.tabicmsprod,1,2) as cstIcms, idgrupo as secao, idsubgrupo as grupo, idsubgrupo1 as subgrupo"
		+ " from produto p inner join itensfornecedor pf on p.idproduto=pf.idproduto"
		+ " inner join produto_preco pp on p.idproduto=pp.idproduto "
        + " where (pf.idfornecedor = :idFornecedor or :idFornecedor is null)"
		+ " and (pp.id_loja =:idLoja or :idLoja is null)" 
        + " and (p.idProduto    = :idProduto    or :idProduto    is null)"
		+ " and (p.idGrupo      = :idGrupo      or :idGrupo      is null)" 
        + " and (p.idSubGrupo   = :idSubGrupo   or :idSubGrupo   is null)"
	    + " and (p.idSubGrupo1  = :idSubGrupo1  or :idSubGrupo1  is null)"
	    + " and (p.descricao like concat(:descricao, '%') or :descricao is null)"
		+ " and (p.produto_cotacao = :participaCotacao or :participaCotacao is null)"
	    + " and (pp.idFamilia   = :idFamilia or :idFamilia is null)" 
        + " and (p.idSituacao   = :idSituacao or :idSituacao is null)"
		+ " order by p.descricao ,  nativeQuery = true)
public List<PedidoCompraItem> listarItensPedidoCompra(@Param("idProduto") Long idProduto, @Param("idLoja") Long idLoja,
		@Param("idFornecedor") Long idFornecedor, @Param("idGrupo") Long idSecao, @Param("idSubGrupo") Long idGrupo,
		@Param("idSubGrupo1") Long idSubgrupo, @Param("descricao") String descricao, @Param("participaCotacao") String participaCotacao,
		@Param("idFamilia") Long idFamilia, @Param("idSituacao") Long idSituacao);

Essa é a forma que esta hoje, eu tentei uma abordagem usando criteria inclusive recebe warning de deprecated, porem a query nao funciona da forma que eu implementei o select. Mas ficou assim:

@SuppressWarnings("unchecked")
@Override
@Transactional(readOnly = true)
public Page<Produto> filtrarPrecoPendente(ProdutoFilter produtoFilter, Pageable pageable) {
	Criteria criteria = manager.unwrap(Session.class).createCriteria(Produto.class);

	paginacaoUtil.preparar(criteria, pageable);
	adicionarFiltro(produtoFilter, criteria);

	return new PageImpl<>(criteria.list(), pageable, total(produtoFilter));
}

private Long total(ProdutoFilter filtro) {
	Criteria criteria = manager.unwrap(Session.class).createCriteria(Produto.class);
	adicionarFiltro(filtro, criteria);
	criteria.setProjection(Projections.rowCount());
	return (Long) criteria.uniqueResult();
}

private void adicionarFiltro(ProdutoFilter filtro, Criteria criteria) {
	if (filtro != null) {
		if (!StringUtils.isEmpty(filtro.getDescricao())) {
			criteria.add(Restrictions.ilike("descricao", filtro.getDescricao(), MatchMode.ANYWHERE));
		}

		if (filtro.getIdSecao() != 0) {
			criteria.add(Restrictions.eq("idgrupo", filtro.getIdSecao()));
		}

		if (filtro.getIdGrupo() != null) {
			criteria.add(Restrictions.eq("idsubgrupo", filtro.getIdGrupo()));
		}

		if (filtro.getIdSubgrupo() != null) {
			criteria.add(Restrictions.eq("idsubgrupo1", filtro.getIdSubgrupo()));
		}

		if (filtro.getEntradaDe() != null) {
			criteria.add(Restrictions.ge("dt_entrada", filtro.getEntradaDe()));
		}

		if (filtro.getEntradaAte() != null) {
			criteria.add(Restrictions.le("dt_entrada", filtro.getEntradaAte()));
		}
	}
}

essa abordagem fica mais legível, mas nao funcionou bem. Por isso gostaria de saber se alguem tem uma sugestao de como refatorar esse metodo.

2 Respostas

campelo.m

Segue um tutorial Spring data
Segue um link da doc

Fabio_Dos_Reis

Acredito que não dê para fazer um refactory bacana só na query que é seu problema, eu gosto de usar jpql e fazer a consulta direto na entidade jpa, mas de qualquer jeito você teria de passar seu filter para verificar os parâmetros e ir “appendando” na query, ficaria paracido com a api criteria do hibernate que você usou.

Criado 19 de novembro de 2019
Ultima resposta 19 de nov. de 2019
Respostas 2
Participantes 3