Hibernate Criteria

Bom dia,

Alguem pode me dizer como faço joins com criteria! pois eu tenho 5 classes: Permissao contem Funcionalidade, que por sua vez é composta de Tela e Acao, e Tela contem Sistema. Então eu quero as permissoes do sistema X!

Eu tô fazendo conforme abaixo, mas tá dando erro de sintaxe:

permissao.funcionalidade.id.tela.sistema.codigo = x, onde id é uma classe que representa uma chave composta de funcionalidade(Tela e Acao)

Voce quer com HQL ou Criteria? Pessoalmente eu prefiro usar Criteria, mas em casos como esse eu prefiro HQL, pois a criteria em vez de ajudar, faz é o código ficar bem mais dificil de entender.

Tem como voce mandar o pedaço do código onde voce faz a consulta e a mensagem de erro que está dando (stack trace)? Porque como eu to vendo parece que nao está quase certo essa sequencia que voce fez, mas nao sei se voce colocou como está no teu código ou só pra dar exemplo.

bom, é isso, se vc mandar o código a gente já arruma em cima dele sem precisar fazer abstracoes… hehee

http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html

Olá gilliard_santos,

gostaria que fosse com Criteria, mas no último caso pode ser com HQL mesmo.

segue abaixo o que fiz:

public Collection obterTodos(Grupo grupo, Sistema sistema) {

	Session session = super.abrirSessao();

	try {
		Criteria select = session.createCriteria(Permissao.class);

		if (grupo != null && grupo.getIdentificador() != null) {
			select.add(Restrictions.eq("ator.identificador", 
									   grupo.getIdentificador()));
		}

		if (sistema != null && sistema.getIdentificador() != null) {
			select.add(Restrictions.eq("funcionalidade.funcionalidadeId.tela.sistema.identificador", 
									   sistema.getIdentificador()));
		}

		return select.list();
	} finally {
		super.fecharSessao(session);
	}

}

classe FuncionalidadeId


public class FuncionalidadeId extends AbstractDTO {

	private Acao acao;
	private Tela tela;
}

o erro é:

[i]

org.hibernate.QueryException: could not resolve property: funcionalidade.funcionalidadeId.tela.sistema.identificador of: br.com.netra.sca.Permissao
oracle.oc4j.rmi.OracleRemoteException: org.hibernate.QueryException: could not resolve property: funcionalidade.funcionalidadeId.tela.sistema.identificador of: br.com.netra.sca.Permissao
[/i]

Um abraço,

Osmar

olha, voce está fazendo com criteria o que seria feito com HQL.
Em HQL voce vai escrevendo no modelo “propriedade.propriedadeDaPropriedade” e assim por diante, porém com Criteria vc precisa fazer subcritérias (por isso que eu comentei que em algunas casos fazer com HQL fica mais simples e legível).

No teu caso ficaria mais ou menos assim


...
Criteria criteria = session.createCriteria(Permissao.class)
.createCriteria("funcionalidade")
.createCriteria("id")
.createCriteria("tela")
.createCriteria("sistema")
.add(Restrictions.eq("codigo", codigo));
return criteria.list();

...

viu o tamanho do negocio que vc tem q fazer?
Com HQL:

...

String hql = "from Permissao p where p.funcionalidade.id.tela.sistema.codigo = :cod";
Query query = session.createQuery(hql);
query.setString("cod", codigo);
return query.list();

...

a idéia tá aí, agora voce escolhe qual a melhor saida pra vc e coloca na tua aplicacao… obviamente esses codigos podem nao rodar de primeiro pq eu to colocando a idéia. Na hora de implementar voce faz os ajustes que forem necessarios e depois posta aqui se funcionou ou nao e como voce fez.
até mais.

gilliard_santos,

Como Criteria não estou conseguindo, pois não está sendo possivel acessar a propriedade tela!
erro: org.hibernate.QueryException: could not resolve property: tela of: br.com.netra.sca.Permissao

Eu acredito que esse erro seja porque tela faz parte de uma chave composta de Funcionalidade. Veja cmo está a class:

public class Funcionalidade{
	private FuncionalidadeId identificador;
	private Set permissoes;
}

e FuncionalidadeId :

public class FuncionalidadeId {
	private Acao acao;
	private Tela tela;
}

Eu fiz justamente o que vc sugeriu:

Criteria select = session.createCriteria(Permissao.class);

            select.createCriteria("funcionalidade");
            select.createCriteria("identificador");
            select.createCriteria("tela");
            select.createCriteria("sistema");
            select.add(Restrictions.eq("identificador", 
                                           sistema.getIdentificador()));

bom, pode ser algum problema relacionado à chave mesmo… eu nao posso te dizer por esperiencia propria pois em casos como esse teu eu acabo usando hql.
Eu também uso criteria pra qse tudo, mas pq quase todas minhas queries sao simples/curtas, nao faço muito join. Em pesquisa maiores como a tua, eu vejo o seguinte: se vai ter muito if no meio, em vez de concatenar string pra adicionar ou nao uma restricao eu uso Criteria; agora quando eu vou ter as mesmas restricoes (como no teu caso) eu uso hql e fica muito mais pratico. As duas ferramentas existem pra escolhermos o melhor momento de usar cada uma.

Pessoal, eu acabei usando query nativa para resolver meu problema, pois com Criteria não tava funcionando devido os erros postados anteriormente. Não sei se é a melhor forma, mas foi a solução que encontrei.

obrigado a todos pela ajuda!

Query nativa? Por que não HQL?

[quote=obs][code]Criteria select = session.createCriteria(Permissao.class);

        select.createCriteria("funcionalidade");
        select.createCriteria("identificador");
        select.createCriteria("tela");
        select.createCriteria("sistema");
        select.add(Restrictions.eq("identificador", 
                                       sistema.getIdentificador()));[/code][/quote]

Não funcionou pois você está criando todas as subcriterias na criteria mãe (“select”). A idéia é justamente você encadear as subcriterias:

Criteria select = session.createCriteria(Permissao.class); select.createCriteria("funcionalidade") .createCriteria("identificador") .createCriteria("tela"); .createCriteria("sistema") .add(Restrictions.eq("identificador", sistema.getIdentificador()));

realmente foi desatençao minha nao comentar…
vc nao fez exatamente oq eu sugeri… vc fez “parecido” e eu nem me toquei que estava errado. se nao fosse o Fabio falar…
E com relacao a usar sql nativa eu também nao vejo motivo, já que com hql é ate mais facil…
mas depois de eu bater tanto nessa tecla de que hql resolve perfeitamente esse problema em um codigo bem menor, eu nao tenho mais o que falar… só que sql nativa é algo que dese ser evitado ao extremo…

Pessoal,

Vejam a minha dúvida:

Preciso fazer um select onde vou agrupar determinada informação.

Basicamente, tenho dois objetos (duas tabelas no banco)

select rep.repoId, count(rea), rep.totSmp
					  from Reanalise rea 
					  join rea.repo rep 
					  group by rep.repoId, rep.totSmp 
					  order by rep.repoId

Este é o HQL e funciona perfeitamente. Ele retorna uma List e cada posição deste lista possui um vetor do tipo Object de 3 posições onde cada posição é um campo do meu select.

A minha dúvida é:

Eu consigo fazer isso via Criteria?

Eu suspeito que não pode ser feito por causa do campo count(rea)… Este campo não faz parte de nenhum dos dois objetos e pelo que pude perceber, qdo vc cria um Criteria vc precisa passar o Objeto no qual será feito.

Em relatórios que precisam desse tipo de coisa, ou seja, agrupar, somar, enfim onde vão ter campos que não estão nos Objetos, eu sempre vou ter que trabalhar com vetores de Object?

Abraço,

Luiz Cantoni

olha, com Criteria tem como fazer sim, agora eu acho que a forma do retorno não vai ser dferente do que você esta recebendo com HQL. A final, como você mesmo disse, esses valores não são atributos de nenhum bean, então que outra forma o hibernate teria para devolve-los?
De qualquer forma de uma olhada aqui http://www.hibernate.org/hib_docs/v3/reference/en/html/querycriteria.html#querycriteria-projection . Eu não costumo usar muitas projeções no meu dia-a-dia então não posso te responder com toda a certeza. Da uma olhada nesse link e quem sabe sirva para responder algo que eu tenha deixado passar…
flw.

Giliard,

Vc tem razão… consegui fazer a partir do Criteria, porém, ficou mais complexo. Nestes casos, acho que o HQL é mais simples.

Obrigado,

Cantoni

Pessoal,

Estou estudando Projection do Hibernate, conforme dica do Gilliard.

A dúvida é:

Como colocar um campo calculado na Projeção?

POr exemplo,

Em um determinado select (hipotético) eu tenho isso aqui:

Select a, count(), count()/2
from…

o count(*)/2 é um campo calculado…

COmo fazer isso com Projection?

Obrigado,

Luiz Cantoni

Galera, eu preciso fazer um join em uma tabela, porém ela não tem relacionamento nenhum com a outra no pojo

queria saber se tem como fazer algo do tipo:

select a.campo1, b.campo2
from tabela1 a
join tabela2 b where (ou seria on?) b.campox = a.campoy
where blablabla

ver se não funciona dessa forma:

select a.campo1, b.campo2 from Objeto1 a inner join fetch a.objetoX.objetoY.objeto2 b
where a.id = b.id and b.id = :param

ou seja, o objeto1 não está diretamento ligado ao objeto2, mas através de outros relacionamentos vc poderá ter acesso ao objeto2

Existe alguma forma de recuperar o SQL ou o HQL resultante de uma Criteria?

Por exemplo nessa criteria:

Criteria crit = sess.createCriteria(Cat.class); List cats = crit.list();

retornar:

obrigado,

Daniel

no hibernate.cfg.xml vc coloca a propriedade:

true

Ok, mas assim o hibernate vai apenas me mostrar o sql usado, eu precisava recuperar o sql gerado pra usar posteriormente.