HQL para Critéria

Olá amigos, gostaria de saber como converter a consuta HQL abaixo, na sua representação em Critéria.

A idéia é: Buscar Acomodações disponíveis
Em outras palavras, buscar acomodaçções que não tenham reservas naquele periodo …
O problema é, como fazer aquele sub-Select… :?

[code] String HQL = “” +
" from Acomodacao as acomodacao" +
" WHERE " +
" (" +
" select count(res) from Reserva as res " +
" WHERE " +
" (" +
" res.dataInicio between :dataInicio and :dataFim" +
" OR " +
" res.dataFim between :dataInicio and :dataFim" +
" )" +
" AND res.acomodacao.id = acomodacao.id " +
" ) = 0" +
" ORDER BY acomodacao.numero" +
"";

	Query query = session.createQuery(HQL);
	
	// Definição dos parâmetros
	query.setDate("dataInicio", dataInicio);
	query.setDate("dataFim", dataFim);

[/code]

Estava fazendo em critéria, como não conseguim resolvi usar HQL…
Mas quero saber como fazer em critéria.

http://www.hibernate.org/hib_docs/reference/en/html/querycriteria-detachedqueries.html

mais especificamente esse exemplo :

DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
    .setProjection( Property.forName("weight") );
session.createCriteria(Cat.class)
    .add( Subqueries.geAll("weight", weights) )
    .list();

Aew galera , consegui, depois de tanto bater cabeça… hehehe
E valeu windsofhell pela dica.

Ta ai pra quem precisar…

:arrow: Antes

String HQL = "" + " from Acomodacao as acomodacao" + " WHERE " + " (" + " select count(res) " + " from Reserva as res " + " inner join res.statusReserva as statusReserva" + " WHERE " + " (" + " res.dataInicio between :dataInicio and :dataFim" + " OR " + " res.dataFim between :dataInicio and :dataFim" + " )" + " AND res.acomodacao.id = acomodacao.id " + " AND statusReserva.descricao <> :statusReserva" + " ) = 0" + " ORDER BY acomodacao.numero" + "";

:arrow: Depois

[code] // Critérias
// ==================
Criteria acomodacaoCriteria = session.createCriteria(Acomodacao.class, "acomodacaoAtual");
DetachedCriteria reservaCriteria = DetachedCriteria.forClass(Reserva.class, "reserva"); // Usado para o sub-select
reservaCriteria.createAlias("statusReserva", "statusReserva", DetachedCriteria.INNER_JOIN);

	acomodacaoCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);  

	
	// Refinação da busca
	// ===============================================, 
	acomodacaoCriteria.add(Restrictions.eq("tipoAcomodacao.id", (long) 1));
	
	
	// Sub-select para busca de reservas
	// se for encontrado mais de 1 reserva "pode" significar que a acomodação não esta disponivel 

	// Retorna a quantidade de Reservas 
	reservaCriteria.setProjection(
			Projections.projectionList()
				.add(Projections.rowCount(), "numReservas")
	);
	
	Criterion reservasCadastrada = Restrictions.or(	
			Restrictions.between("dataInicio", dataInicio, dataFim),
			Restrictions.between("dataFim", dataInicio, dataFim)
	);
	
	
	// Pegar somente as reservas "não canceladas"
	reservaCriteria.add(Restrictions.not(Restrictions.eq("statusReserva.descricao", Constantes.STATUS_RESERVA_CANCELADA)));

	reservaCriteria.add(reservasCadastrada);
	// Usado para buscar as reservas da acomodação atual
	reservaCriteria.add(Restrictions.eqProperty("acomodacao.id", "acomodacaoAtual.id"));



	// Se as reservas for igual a 0, significa que está disponivel
	acomodacaoCriteria.add(Subqueries.eq(0, reservaCriteria));

	
	List<Object> acomodacoes = acomodacaoCriteria.list();[/code]