Tenho esta consulta
@Query(value = "SELECT DISTINCT new Categoria(c.id, c.nome, c.metadadoAuditoria.statusDoRegistro, c.tipoCategoria, s, s.nome) FROM InsumoLoja e LEFT OUTER JOIN e.insumo i LEFT OUTER JOIN i.grupo g RIGHT OUTER JOIN g.categoria c LEFT OUTER JOIN c.setor s WHERE (UPPER(c.nome) LIKE :nome or :nome is null) AND (e.loja.id = :idLoja or :idLoja is null) ")
Page<Categoria> pesquisarRetornandoCategoria(@Param("nome") String nome, @Param("idLoja") Long idLoja, Pageable pageable);
Gerou esta consulta, o que traz o resultado correto
select distinct categoria3_.PK_CATEGORIA as col_0_0_, categoria3_.DS_NOME as col_1_0_, categoria3_.ST_REGISTRO as col_2_0_, categoria3_.ST_CATEGORIA_TIPO as col_3_0_, setor4_.PK_SETOR as col_4_0_, setor4_.DS_NOME as col_5_0_ from TAB_INSUMO_LOJA insumoloja0_ left outer join TAB_INSUMO insumo1_ on insumoloja0_.FK_INSUMO=insumo1_.PK_INSUMO left outer join TAB_GRUPO grupo2_ on insumo1_.FK_GRUPO=grupo2_.PK_GRUPO right outer join TAB_CATEGORIA categoria3_ on grupo2_.FK_CATEGORIA=categoria3_.PK_CATEGORIA left outer join TAB_SETOR setor4_ on categoria3_.FK_SETOR=setor4_.PK_SETOR where (upper(categoria3_.DS_NOME) like ? or ? is null) and (insumoloja0_.FK_LOJA=? or ? is null) order by categoria3_.DS_NOME asc offset 0 rows fetch next ? rows only
Só que o count, gera errado no meu ponto de vista aqui traz 413 e só tem 17
gera assim:
select count(distinct insumoloja0_.PK_INSUMO_LOJA) as col_0_0_ from TAB_INSUMO_LOJA insumoloja0_ left outer join TAB_INSUMO insumo1_ on insumoloja0_.FK_INSUMO=insumo1_.PK_INSUMO left outer join TAB_GRUPO grupo2_ on insumo1_.FK_GRUPO=grupo2_.PK_GRUPO right outer join TAB_CATEGORIA categoria3_ on grupo2_.FK_CATEGORIA=categoria3_.PK_CATEGORIA left outer join TAB_SETOR setor4_ on categoria3_.FK_SETOR=setor4_.PK_SETOR where (upper(categoria3_.DS_NOME) like ? or ? is null) and (insumoloja0_.FK_LOJA=? or ? is null)
devendo ser assim, porque traz 17 registros
select count(distinct categoria3_.PK_CATEGORIA) as col_0_0_ from TAB_INSUMO_LOJA insumoloja0_ left outer join TAB_INSUMO insumo1_ on insumoloja0_.FK_INSUMO=insumo1_.PK_INSUMO
left outer join TAB_GRUPO grupo2_ on insumo1_.FK_GRUPO=grupo2_.PK_GRUPO
right outer join TAB_CATEGORIA categoria3_ on grupo2_.FK_CATEGORIA=categoria3_.PK_CATEGORIA
left outer join TAB_SETOR setor4_ on categoria3_.FK_SETOR=setor4_.PK_SETOR where (upper(categoria3_.DS_NOME) like ? or ? is null)
and (insumoloja0_.FK_LOJA=? or ? is null)
O que pode ser ?
Poste o código completo da entidade?
1 curtida
Categoria
package br.com.ghnetsoft.comprasfood.model;
import static javax.persistence.EnumType.STRING;
import static javax.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;
import static lombok.AccessLevel.PUBLIC;
import static org.hibernate.annotations.CacheConcurrencyStrategy.NONSTRICT_READ_WRITE;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import br.com.ghnetsoft.comprasfood.model.enuns.ProdutoInsumoEnum;
import br.com.ghnetsoft.principal.auditoria.AuditableBase;
import br.com.ghnetsoft.principal.enuns.StatusDoRegistroEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@EqualsAndHashCode(of = "id", callSuper = false)
@Setter
@Getter
@Entity
@Builder
@Table(name = "TAB_CATEGORIA")
@NoArgsConstructor(access = PUBLIC)
@AllArgsConstructor(access = PROTECTED)
@Cache(usage = NONSTRICT_READ_WRITE)
public class Categoria extends AuditableBase {
private static final long serialVersionUID = -1159628968264815235L;
@Id
@Column(name = "PK_CATEGORIA")
@GeneratedValue(strategy = IDENTITY)
private Long id;
@ManyToOne(targetEntity = Setor.class)
@JoinColumn(name = "FK_SETOR")
private Setor setor;
@Column(name = "DS_NOME")
private String nome;
@Enumerated(STRING)
@Column(name = "ST_CATEGORIA_TIPO", length = 7)
private ProdutoInsumoEnum tipoCategoria;
public Categoria(Long id, String nome, StatusDoRegistroEnum statusDoRegistro, ProdutoInsumoEnum tipoCategoria, Setor setor, String nomeSetor) {
this.id = id;
this.nome = nome;
this.getMetadadoAuditoria().setStatusDoRegistro(statusDoRegistro);
this.tipoCategoria = tipoCategoria;
this.setor = setor;
this.setor.setNome(nomeSetor);
}
}
InsumoLoja
package br.com.ghnetsoft.comprasfood.model;
import static javax.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;
import static org.hibernate.annotations.CacheConcurrencyStrategy.NONSTRICT_READ_WRITE;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import br.com.ghnetsoft.principal.auditoria.AuditableBase;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@EqualsAndHashCode(of = "id", callSuper = false)
@Setter
@Getter
@Entity
@Builder
@Table(name = "TAB_INSUMO_LOJA")
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor(access = PROTECTED)
@Cache(usage = NONSTRICT_READ_WRITE)
public class InsumoLoja extends AuditableBase {
private static final long serialVersionUID = -999094130427415229L;
@Id
@Column(name = "PK_INSUMO_LOJA")
@GeneratedValue(strategy = IDENTITY)
private Long id;
@ManyToOne(targetEntity = Insumo.class)
@JoinColumn(name = "FK_INSUMO")
private Insumo insumo;
@ManyToOne(targetEntity = Loja.class)
@JoinColumn(name = "FK_LOJA")
private Loja loja;
@Column(name = "NR_QUANTIDADE_ATUAL")
private BigDecimal quantidadeAtual;
@Column(name = "NR_QUANTIDADE_MINIMO")
private BigDecimal quantidadeMinima;
@Column(name = "NR_QUANTIDADE_PEDIDO")
private BigDecimal quantidadePedido;
@Column(name = "NR_DIAS_INVENTARIO")
private Long diasInventario;
@Column(name = "VR_CUSTO_MEDIO")
private BigDecimal custoMedio;
@Column(name = "VR_ULTIMO_CUSTO")
private BigDecimal ultimoCusto;
@Column(name = "DT_ULTIMA_COMPRA")
private Date ultimaCompra;
@Column(name = "DS_PLANO_CONTA_CONTABILIDADE")
private String planoContaContabilidade;
}
Insumo
package br.com.ghnetsoft.comprasfood.model;
import static javax.persistence.EnumType.STRING;
import static javax.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;
import static lombok.AccessLevel.PUBLIC;
import static org.hibernate.annotations.CacheConcurrencyStrategy.NONSTRICT_READ_WRITE;
import java.util.Collection;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import br.com.ghnetsoft.comprasfood.model.enuns.InsumoFaseEnum;
import br.com.ghnetsoft.principal.auditoria.AuditableBase;
import br.com.ghnetsoft.principal.enuns.SimNaoEnum;
import br.com.ghnetsoft.principal.enuns.StatusDoRegistroEnum;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@EqualsAndHashCode(of = "id", callSuper = false)
@Setter
@Getter
@Entity
@Table(name = "TAB_INSUMO")
@NoArgsConstructor(access = PUBLIC)
@AllArgsConstructor(access = PROTECTED)
@Cache(usage = NONSTRICT_READ_WRITE)
public class Insumo extends AuditableBase {
private static final long serialVersionUID = -4885091941126527156L;
@Id
@Column(name = "PK_INSUMO")
@GeneratedValue(strategy = IDENTITY)
private Long id;
@ManyToOne(targetEntity = Unidade.class)
@JoinColumn(name = "FK_UNIDADE")
private Unidade unidade;
@ManyToOne(targetEntity = Grupo.class)
@JoinColumn(name = "FK_GRUPO")
private Grupo grupo;
@Column(name = "CD_CODIGO_EAN")
private String codigoEan;
@Column(name = "CD_CODIGO_EXPORTACAO")
private String codigoExportacao;
@Column(name = "DS_NOME")
private String nome;
@Column(name = "DS_DESCRICAO")
private String descricao;
@Enumerated(STRING)
@Column(name = "ST_PESAVEL")
private SimNaoEnum pesavel;
@Enumerated(STRING)
@Column(name = "ST_FASE")
private InsumoFaseEnum fase;
@OneToMany(mappedBy = "insumo", targetEntity = ProdutoInsumo.class)
@Cache(usage = NONSTRICT_READ_WRITE)
@BatchSize(size = 20)
private Collection<ProdutoInsumo> produtosInsumos;
@OneToMany(mappedBy = "insumo", targetEntity = InsumoLoja.class)
@Cache(usage = NONSTRICT_READ_WRITE)
@BatchSize(size = 20)
private Collection<InsumoLoja> insumoLojas;
@OneToMany(mappedBy = "insumo", targetEntity = InsumoLojaFornecedor.class)
@Cache(usage = NONSTRICT_READ_WRITE)
@BatchSize(size = 20)
private Collection<InsumoLojaFornecedor> insumosLojasFornecedores;
public Insumo(Long id, String codigoEan, String nome, StatusDoRegistroEnum statusDoRegistro, Unidade unidade, Grupo grupo, InsumoFaseEnum fase, String grupoNome, String unidadeNome) {
this.id = id;
this.codigoEan = codigoEan;
this.nome = nome;
this.getMetadadoAuditoria().setStatusDoRegistro(statusDoRegistro);
this.unidade = unidade;
this.grupo = grupo;
this.fase = fase;
this.unidade.setNome(unidadeNome);
this.grupo.setNome(grupoNome);
}
}
Grupo
package br.com.ghnetsoft.comprasfood.model;
import static javax.persistence.EnumType.STRING;
import static javax.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;
import static org.hibernate.annotations.CacheConcurrencyStrategy.NONSTRICT_READ_WRITE;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import br.com.ghnetsoft.comprasfood.model.enuns.ProdutoInsumoEnum;
import br.com.ghnetsoft.principal.auditoria.AuditableBase;
import br.com.ghnetsoft.principal.enuns.StatusDoRegistroEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@EqualsAndHashCode(of = "id", callSuper = false)
@Setter
@Getter
@Entity
@Builder
@Table(name = "TAB_GRUPO")
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor(access = PROTECTED)
@Cache(usage = NONSTRICT_READ_WRITE)
public class Grupo extends AuditableBase {
private static final long serialVersionUID = -373887947568758268L;
@Id
@Column(name = "PK_GRUPO")
@GeneratedValue(strategy = IDENTITY)
private Long id;
@ManyToOne(targetEntity = Categoria.class)
@JoinColumn(name = "FK_CATEGORIA")
private Categoria categoria;
@Column(name = "DS_NOME")
private String nome;
@Enumerated(STRING)
@Column(name = "ST_GRUPO_TIPO")
private ProdutoInsumoEnum grupoTipo;
public Grupo(Long id, String nome, StatusDoRegistroEnum statusDoRegistro, ProdutoInsumoEnum grupoTipo, Categoria categoria, String categoriaNome) {
this.id = id;
this.nome = nome;
this.getMetadadoAuditoria().setStatusDoRegistro(statusDoRegistro);
this.grupoTipo = grupoTipo;
this.categoria = categoria;
this.categoria.setNome(categoriaNome);
}
}
Setor
package br.com.ghnetsoft.comprasfood.model;
import static javax.persistence.EnumType.STRING;
import static javax.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;
import static org.hibernate.annotations.CacheConcurrencyStrategy.NONSTRICT_READ_WRITE;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import br.com.ghnetsoft.comprasfood.model.enuns.ProdutoInsumoEnum;
import br.com.ghnetsoft.principal.auditoria.AuditableBase;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@EqualsAndHashCode(of = "id", callSuper = false)
@Setter
@Getter
@Entity
@Builder
@Table(name = "TAB_SETOR")
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor(access = PROTECTED)
@Cache(usage = NONSTRICT_READ_WRITE)
public class Setor extends AuditableBase {
private static final long serialVersionUID = -1825560977083410942L;
@Id
@Column(name = "PK_SETOR")
@GeneratedValue(strategy = IDENTITY)
private Long id;
@Column(name = "DS_NOME")
private String nome;
@Enumerated(STRING)
@Column(name = "ST_SETOR_TIPO")
private ProdutoInsumoEnum setorTipo;
}
A questão é que tenho que buscar todas categorias.
Um dos filtros da tela é a loja.
Usa SQL + DTO, bem mais prático e sem essa confusao de classes de entidades.
1 curtida
E pro count nem DTO vai precisar, só mesmo fazer o SQL e retornar um int ou long.
1 curtida
@guilhermebhte aconselho verificar o mapeamento das entidades associadas, esses OneToMany, ManyToOne, e etc.
Observe que esta gerando outer joins
estranhos para fazer um count
. Provavelmente essas classes estao com mapeamento errado em relação a sua regra de negócio, pois segundo você disse, não está retornando conforme o esperado.
PS: Se voce nao conseguir resolver esse bug, faça um um método count
com a query
customizada como vc deseja, porém, isso está com cara de erro no mapeamento, e pode trazer outras consequências se não for resolvido.
1 curtida