Duvida em Criteria (Hibernate)

Olá galera Java.
Eu tenho o Seguinte relacionamento:
Cliente 1 ---- * Assunto 1 ------ * Noticia.

Gostaria de saber se tem como eu buscar as Noticias somente do Cliente X, usando critéria.

Eu consegui isso usando HQL, mas quero(tenho) que usar critéria.

Em HQL, fica:
String queryString = "FROM Noticia WHERE assunto.cliente.id = " + cliente.getId();

Como se aplica esse tipo de restrição em Critéria ?

RicardoCobain,

Acredito que você deverá que utilizar algum campo de identificação unica para este cliente, como um IDCliente ou outra coisa do tipo, sendo que você deverá informar ao Hibernet que somente deve trazer os dados deste cliente, uma boa forma de você fazer isso, acredito eu, e passando apenas este cliente e não uma coleção dque contenha todos os clientes para o hibernet.

Eu tb estou com uma consulta semelhante, tenho que selecionar uma lote de que pode ter n itens, e desses itens tenho que trazer somente os que tem status igual a 5. Quando realizei a consulta a criteria realmente me retornou o resultado correto, ou seja, os lotes que tinham itens que atendiam minha condição do status, porem não fez o filtro neles, retornando todos os itens do lote independente de status. Olha meu "POBREMA" ai! http://guj.com.br/posts/list/95125.java

Assim…, encontrei uma forma de resolver meu problema, pode não ser tão viável mas funciona, quando pego a lista da minha consulta faço um laço que percorre cada lote e pega seus itens e faz a checagem…

[code]lotes = criteria.list();

	for (int i = 0; i < lotes.size(); i++){
		
		itensDolote = lotes.get(i).getItensDeLote();
		
		System.out.println("LOTE "+lotes.get(i).getId()+ " QTD ITENS " +itensDolote.size());
		
		for (int c = 0; c < itensDolote.size(); c++ ){
			
			if (itensDolote.get(c).getStatusItem().getId() != 5L ){
				
				System.out.println("ITEM EXCLUIDO  " + itensDolote.get(c).getId()  +" LOTE  "+lotes.get(i).getId());
				
				itensDolote.remove(c);
			}
		}
	}[/code]

O chato disso é que perco desempenho, mas estive tentando e realmente não deu certo com critéria. Se vcs encontrarem uma solução posta ai!

Abraços pessoal!

RicardoCobain, tente fazer assim:

[code]Criteria c1 = session.createCriteria(Cliente.class);
c1.add(Restrictions.eq(“id”, cliente.getId()));

Criteria c2 = c1.createCriteria(“assunto”);
Criteria c3 = c2.createCriteria(“noticia”);

c3.list();[/code]Não cheguei a fazer isso “em 3 níveis”, mas creio que assim vai funcionar. Testa aew e depois diz se é isso mesmo!

toninhocell, o seu é mais fácil de resolver:

[code]Criteria c1 = session.createCriteria(Lote.class);
c1.add(Restrictions.eq(“id”, id)); // condição de seleção do lote, se é que tem
Criteria c2 = c1.createCriteria(“itens”);

c2.add(Restrictions.eq(“status”, 5));
c2.list();[/code]Isso vai trazer todos os itens com status igual a 5 no lote selecionado.

Eu num testei nenhum dos dois :XD: , confiram se está funcionando corretamente.
Blz? Flw! :thumbup:

von.juliano no meu caso eu passo ou não um lote, sendo que no momento em que não passar ele deve fazer esta consulta para todo os lotes da base e fazer a restrição para todos o sub-itens de lote…

[code]Criteria c1 = session.createCriteria(Lote.class);
c1.add(Restrictions.eq(“id”, id)); // condição de seleção do lote, se é que tem
Criteria c2 = c1.createCriteria(“itens”);

c2.add(Restrictions.eq(“status”, 5));
c2.list();[/code]

Se você não passar o lote, é só não utilizar a linha com o comentário, e a consulta trará todos os itens de todos os lotes.

von.juliano olha ai como to fazendo. Realmente não está funcionando, está me retornando todos os itens do lote independente do status.

A primeira restrição está ok, ou seja, está me retornando somente os lotes que estão abertos, mas a segunda dos itens de lote não está… :?

[code]
Criteria criteria = getSession().createCriteria(Lote.class);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

criteria.createAlias(“statusLote”, “statusDoLote”);

	criteria.add(Restrictions.eq("statusLote.id", 1L)); // 1 = ABERTO, 2 = FECHADO
	
	Criteria c2 = criteria.createCriteria("itensDeLote");
	
	c2.add(Restrictions.eq("statusItem.id",5L));
	
	return criteria.list();[/code]

Você tem um StatusItem dentro de cada Item, e é nele que está o valor do status de cada Item, é isso mesmo?

Cola o sql gerado pelo hibernate aqui pra facilitar.

[quote=von.juliano]Você tem um StatusItem dentro de cada Item, e é nele que está o valor do status de cada Item, é isso mesmo?

Cola o sql gerado pelo hibernate aqui pra facilitar.[/quote]

É isso ai!!! olha o que sai…

Ele gera duas consultas, na primeira ele realmente está fazendo a consulta que quero, porem, na segunda consulta ele de alguma forma perde os dados retornados na consulta antes feita e ai meu dados já não são os que eu espero receber…

11:04:33,828 INFO [STDOUT] Hibernate: select this_.ID as ID205_7_, this_.DATA_HORA_CRIACAO as DATA2_205_7_, this_.MES_ANO_REFERENCIA as MES3_205_7_, this_.FK_ESTABELECIMENTO_ID as FK5_205_7_, this_.FK_STATUS_LOTE_ID as FK4_205_7_, estabeleci4_.ID as ID204_0_, estabeleci4_.RAZAO_SOCIAL as RAZAO2_204_0_, estabeleci4_.INSCRICAO_ESTADUAL as INSCRICAO3_204_0_, estabeleci4_.EMAIL as EMAIL204_0_, estabeleci4_.TELEFONE as TELEFONE204_0_, estabeleci4_.ABREVIATURA as ABREVIAT6_204_0_, estabeleci4_.FROTA as FROTA204_0_, statusdolo1_.ID as ID209_1_, statusdolo1_.DESCRICAO as DESCRICAO209_1_, itemdelote2_.ID as ID202_2_, itemdelote2_.FK_CLIENTE_ID as FK7_202_2_, itemdelote2_.FK_LOTE_ID as FK8_202_2_, itemdelote2_.NUMERO_NOTA as NUMERO2_202_2_, itemdelote2_.SERIE_NOTA as SERIE3_202_2_, itemdelote2_.DATA_EMISSAO_NOTA as DATA4_202_2_, itemdelote2_.DATA_RECEBTO_NOTA as DATA5_202_2_, itemdelote2_.FK_STATUS_ITEM_LOTE_ID as FK6_202_2_, cliente7_.ID as ID201_3_, cliente7_.CGC_CPF as CGC2_201_3_, cliente7_.FAVORECIDO as FAVORECIDO201_3_, cliente7_.CGC_CPF_FAVORECIDO as CGC4_201_3_, cliente7_.NOME as NOME201_3_, cliente7_.FANTASIA as FANTASIA201_3_, cliente7_.INSCRICAO_ESTADUAL as INSCRICAO7_201_3_, cliente7_.NUMERO_CEI as NUMERO8_201_3_, cliente7_.EMAIL as EMAIL201_3_, cliente7_.NRO_FUNCIONARIOS as NRO10_201_3_, cliente7_.VALOR_DOACAO as VALOR11_201_3_, cliente7_.CODIGO as CODIGO201_3_, cliente7_.FILIAL as FILIAL201_3_, cliente7_.NOTA_FISCAL_FROTA as NOTA14_201_3_, lote8_.ID as ID205_4_, lote8_.DATA_HORA_CRIACAO as DATA2_205_4_, lote8_.MES_ANO_REFERENCIA as MES3_205_4_, lote8_.FK_ESTABELECIMENTO_ID as FK5_205_4_, lote8_.FK_STATUS_LOTE_ID as FK4_205_4_, statuslote9_.ID as ID209_5_, statuslote9_.DESCRICAO as DESCRICAO209_5_, statusitem10_.ID as ID208_6_, statusitem10_.DESCRICAO as DESCRICAO208_6_ from adeb.CNF_LOTE this_, adeb.CNFADC_CONVENIADAS estabeleci4_, adeb.CNF_STATUS_LOTE statusdolo1_, adeb.CNF_ITEM_LOTE itemdelote2_, adeb.CNFADC_CLIENTES cliente7_, adeb.CNF_LOTE lote8_, adeb.CNF_STATUS_LOTE statuslote9_, adeb.CNF_STATUS_ITEM_LOTE statusitem10_ where this_.FK_ESTABELECIMENTO_ID=estabeleci4_.ID and this_.FK_STATUS_LOTE_ID=statusdolo1_.ID and this_.ID=itemdelote2_.FK_LOTE_ID and itemdelote2_.FK_CLIENTE_ID=cliente7_.ID(+) and itemdelote2_.FK_LOTE_ID=lote8_.ID(+) and lote8_.FK_STATUS_LOTE_ID=statuslote9_.ID(+) and itemdelote2_.FK_STATUS_ITEM_LOTE_ID=statusitem10_.ID(+) and this_.FK_STATUS_LOTE_ID=? and itemdelote2_.FK_STATUS_ITEM_LOTE_ID=? 11:04:33,843 INFO [STDOUT] Hibernate: select itensdelot0_.FK_LOTE_ID as FK8_3_, itensdelot0_.ID as ID3_, itensdelot0_.ID as ID202_2_, itensdelot0_.FK_CLIENTE_ID as FK7_202_2_, itensdelot0_.FK_LOTE_ID as FK8_202_2_, itensdelot0_.NUMERO_NOTA as NUMERO2_202_2_, itensdelot0_.SERIE_NOTA as SERIE3_202_2_, itensdelot0_.DATA_EMISSAO_NOTA as DATA4_202_2_, itensdelot0_.DATA_RECEBTO_NOTA as DATA5_202_2_, itensdelot0_.FK_STATUS_ITEM_LOTE_ID as FK6_202_2_, cliente1_.ID as ID201_0_, cliente1_.CGC_CPF as CGC2_201_0_, cliente1_.FAVORECIDO as FAVORECIDO201_0_, cliente1_.CGC_CPF_FAVORECIDO as CGC4_201_0_, cliente1_.NOME as NOME201_0_, cliente1_.FANTASIA as FANTASIA201_0_, cliente1_.INSCRICAO_ESTADUAL as INSCRICAO7_201_0_, cliente1_.NUMERO_CEI as NUMERO8_201_0_, cliente1_.EMAIL as EMAIL201_0_, cliente1_.NRO_FUNCIONARIOS as NRO10_201_0_, cliente1_.VALOR_DOACAO as VALOR11_201_0_, cliente1_.CODIGO as CODIGO201_0_, cliente1_.FILIAL as FILIAL201_0_, cliente1_.NOTA_FISCAL_FROTA as NOTA14_201_0_, statusitem2_.ID as ID208_1_, statusitem2_.DESCRICAO as DESCRICAO208_1_ from adeb.CNF_ITEM_LOTE itensdelot0_, adeb.CNFADC_CLIENTES cliente1_, adeb.CNF_STATUS_ITEM_LOTE statusitem2_ where itensdelot0_.FK_CLIENTE_ID=cliente1_.ID and itensdelot0_.FK_STATUS_ITEM_LOTE_ID=statusitem2_.ID and itensdelot0_.FK_LOTE_ID in ( select this_.ID from adeb.CNF_LOTE this_, adeb.CNFADC_CONVENIADAS estabeleci4_, adeb.CNF_STATUS_LOTE statusdolo1_, adeb.CNF_ITEM_LOTE itemdelote2_, adeb.CNFADC_CLIENTES cliente7_, adeb.CNF_LOTE lote8_, adeb.CNF_STATUS_LOTE statuslote9_, adeb.CNF_STATUS_ITEM_LOTE statusitem10_ where this_.FK_ESTABELECIMENTO_ID=estabeleci4_.ID and this_.FK_STATUS_LOTE_ID=statusdolo1_.ID and this_.ID=itemdelote2_.FK_LOTE_ID and itemdelote2_.FK_CLIENTE_ID=cliente7_.ID(+) and itemdelote2_.FK_LOTE_ID=lote8_.ID(+) and lote8_.FK_STATUS_LOTE_ID=statuslote9_.ID(+) and itemdelote2_.FK_STATUS_ITEM_LOTE_ID=statusitem10_.ID(+) and this_.FK_STATUS_LOTE_ID=? and itemdelote2_.FK_STATUS_ITEM_LOTE_ID=? )

Putz, é engraçado como quando você procura um problema, você nunca pensa no mais simples primeiro! :mrgreen:
Achei o erro, mude essa linha:

return criteria.list();para

return c2.list();Blz? Flw! :thumbup:

[quote=von.juliano]Putz, é engraçado como quando você procura um problema, você nunca pensa no mais simples primeiro! :mrgreen:
Achei o erro, mude essa linha:

return criteria.list();para

return c2.list();Blz? Flw! :thumbup:
[/quote]

Parece brincadeira mas executando assim e ainda ocorre a mesma coisa…

[code]
Criteria criteria = getSession().createCriteria(Lote.class);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

    // LOTES QUE ESTAO ABERTOS
	criteria.createAlias("statusLote", "statusDoLote");
	
	criteria.add(Restrictions.eq("statusLote.id", 1L)); // 1 = ABERTO, 2 = FECHADO
	
	Criteria c2 = criteria.createCriteria("itensDeLote");
	
	c2.add(Restrictions.eq("statusItem.id",5L));
	
	return c2.list();[/code] :shock:

Cara não deu muito certo, porque quando eu executo: clipCriteria.list(); ele está me retornando um List<Cliente> e não um List<Clip>, ai da uma : ClassCastException

Fiz igual como vc disse:

[code] Criteria clienteCriteria = session.createCriteria(Cliente.class);
clienteCriteria.add(Restrictions.eq(“id”, cliente.getId()));

		Criteria assuntoCriteria = clienteCriteria.createCriteria("ORM_Assuntos");
		
		Criteria clipCriteria = assuntoCriteria.createCriteria("ORM_Clips");
		clipCriteria.add(Restrictions.eq("dataCadastro", new Date()));
		
		List&lt;Clip&gt; lista = clipCriteria.list();
		
		for (Clip clip : lista) {
			// .....
		}[/code]

Clip, é a Mesma coisa de Notícia. :slight_smile:

Blz Ricardo :smiley:

Agora só falta descobrir por que o do toninho (que eu pensei que ia ser mais fácil) num tá funcionando! :XD:

[quote=von.juliano]Blz Ricardo :smiley:

Agora só falta descobrir por que o do toninho (que eu pensei que ia ser mais fácil) num tá funcionando! :XD: [/quote]

De veras… isso ta uma inhaca aqui. Posso fazer como citei antes mas perco com o desempenho, afinal de contas isso quem tem que fazer é o banco e não eu kkkkkkkkkkkkk

Ahhhh… sakei porque, botei pra exibir o SQL e vique quando começava com o:
# Criteria c1 = session.createCriteria(Cliente.class);

Ele dava um Select era no Cliente, o que eu fiz foi só inverter o Processo…

[code] Criteria clipCriteria = session.createCriteria(Clip.class);
clipCriteria.add(Restrictions.eq(“dataCadastro”, new Date()));

		Criteria assuntoCriteria = clipCriteria.createCriteria("assunto");
		
		
		Criteria clienteCriteria = assuntoCriteria.createCriteria("cliente");
		clienteCriteria.add(Restrictions.eq("id", cliente.getId()));			
		
		
		List&lt;Clip&gt; lista = clipCriteria.list();[/code]

Não sabia desse comportamento em Criteria , pensei que instCriteria.createCriteria(“relacionamento”); seria a mesma coisa de: session.createCriteria(Objeto.class);
Cara Critéria é show de bola, nunca mais quero saber de SQL

Agora so quero entender um poco mais, como funciona a questão de Inner Join, Left Join,
– edit –
Por vejo o SQL gerado pelo hibernate e lá tem um monte de select, com coisas que n me interessam, tipo:

Pq ele esta dando um select nos relacionamentos que o cliente tem (foi o que pude perceber)
Isso pode gerar perce de desempenho certo ? O que posso fazer pra resolver isso ?

Quem conhecer algum material bom sobre isso me passa… valeu. :wink:

Eu tentei te passar a idéia, num era bem aquilo, mas se você conseguiu resolver tá valendo! :smiley:

Toninho, a classe StatusItem está anotada como @Embeddable ?

[quote=von.juliano]Eu tentei te passar a idéia, num era bem aquilo, mas se você conseguiu resolver tá valendo! :smiley:

Toninho, a classe StatusItem está anotada como @Embeddable ?[/quote]

Não está, poderia ser esse o problema… :?:

Se ele não estiver anotado, ele não tem uma associação com a entidade. Vê se resolve aew.

Flw! :thumbup:

[quote=von.juliano]Se ele não estiver anotado, ele não tem uma associação com a entidade. Vê se resolve aew.

Flw! :thumbup: [/quote]

Esta entidade está sim anotada, olha como ta lá…

Na entidade Lote

@OneToMany(fetch = FetchType.EAGER, mappedBy = "lote")
	@org.hibernate.annotations.Fetch(FetchMode.SUBSELECT)
	public List<ItemDeLote> getItensDeLote() {
		return itensDeLote;
	}

	public void setItensDeLote(List<ItemDeLote> itensDeLote) {
		this.itensDeLote = itensDeLote;
	}

Na entidade ItemDeLote

[code]@ManyToOne
@JoinColumn(name = “FK_LOTE_ID”, nullable = false)
public Lote getLote() {
return lote;
}

public void setLote(Lote lote) {
	this.lote = lote;
}

@OneToOne
@JoinColumn(name = "FK_STATUS_ITEM_LOTE_ID", nullable = false)
public StatusItemDeLote getStatusItem() {
	return statusItem;
}

public void setStatusItem(StatusItemDeLote statusItem) {
	this.statusItem = statusItem;
}

[/code]

ItemDeLote tem referencias para lote e para Status do item de lote.

Pessoal GRAÇAS A DEUS consegui resolver o problema da consulta com sub-registros. Onde tinha lotes e restrições nos itens de lotes…

Olhem ai como ficou…

[code]

public List<Lote> findLotes(
Estabelecimento estabelecimento, Cliente cliente ) {

	Criteria criteria = getSession().createCriteria(Lote.class);
	criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
	
	Collection&lt;Long&gt; ids = new ArrayList&lt;Long&gt;();

	ids.add(2L);
	ids.add(11L);
	ids.add(3L);
	ids.add(4L);
	ids.add(6L);
	ids.add(7L);
	
	// ESTABELECIMENTO.
	if (estabelecimento.getId() != null ) {
		
		criteria.add(Restrictions.eq("estabelecimento", estabelecimento));
		
	}
	
	criteria.createCriteria("itensDeLote", "itemLote", Criteria.LEFT_JOIN);

	// CLIENTE.
	if (cliente.getId() != null) {
		
		criteria.createCriteria("itemLote.cliente", "itemLoteCliente", Criteria.LEFT_JOIN);
		
		criteria.add(Restrictions.eq("itemLoteCliente.id", cliente.getId()));
		
	}
	
	criteria.add(Restrictions.in("itemLote.statusItem.id", ids));		
	
	return criteria.list();
	
}[/code]

Nesta consulta quando informado o cliente são retornados os itens de lote desse cliente em todos os lotes de todos os estabelecimentos, caso seja informando também o estabelecimento são informados todos os lotes desse cliente para o estabelecimento informado e caso nada seja informado é realizada a consulta genérica…

Show, deu certo! :lol:

Abraços pessoal e obrigado pela força!