[Resolvido] Busca com Criteria não retorna resultados

Oi pessoal!
Fiz uma ferramenta de pesquisa com Criteria, mas só dá resultados colocando o valor mínimo e máximo em conjunto com outro campo para pesquisa, se pesquisar imóvel por bairro, cidade ou estado sem digitar os valores, não retorna nada.
Tentei assim:

	public List<Imovel> busca(String bairro, String cidade, String estado, BigDecimal valorMin, BigDecimal valorMax) {
		return session.createCriteria(Imovel.class)		
	    .add(Restrictions.ilike("bairro", "%"+bairro+"%"))
	    .add(Restrictions.ilike("cidade", "%"+cidade+"%"))
	    .add(Restrictions.ilike("estado", "%"+estado+"%"))
	    .add(Restrictions.between("valor", valorMin, valorMax))
	    .list();
	}

E assim:

public List<Imovel> busca(String bairro, String cidade, String estado, BigDecimal valorMin, BigDecimal valorMax) {
		return session.createCriteria(Imovel.class)		
	    .add(Restrictions.ilike("bairro", bairro, MatchMode.ANYWHERE))
	    .add(Restrictions.ilike("cidade", cidade, MatchMode.ANYWHERE))
	    .add(Restrictions.ilike("estado", estado, MatchMode.ANYWHERE))
	    .add(Restrictions.between("valor", valorMin, valorMax))
	    .list();
	}

Esta é a stacktrace:

17:34:18,088 DEBUG [OgnlParametersProvider] Applying bairro with [tijuca]
17:34:18,088 DEBUG [OgnlParametersProvider] Applying cidade with []
17:34:18,089 DEBUG [OgnlParametersProvider] Applying estado with []
17:34:18,089 DEBUG [OgnlParametersProvider] Applying valorMax with []
17:34:18,090 DEBUG [OgnlParametersProvider] Applying valorMin with []
17:34:18,091 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for IndexController.busca(String, String, String, BigDecimal, BigDecimal) as [bairro, cidade, estado, valorMin, valorMax]
17:34:18,091 DEBUG [ParametersInstantiatorInterceptor] Parameter values for [DefaultResourceMethod: IndexController.buscaIndexController.busca(String, String, String, BigDecimal, BigDecimal)] are [tijuca, , , null, null]
17:34:18,103 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ExecuteMethodInterceptor
17:34:18,104 DEBUG [ExecuteMethodInterceptor] Invoking IndexController.busca(String, String, String, BigDecimal, BigDecimal)
Hibernate: 
    select
        this_.id_imovel as id1_11_0_,
        this_.area as area11_0_,
        this_.bairro as bairro11_0_,
        this_.categoria as categoria11_0_,
        this_.cep as cep11_0_,
        this_.cidade as cidade11_0_,
        this_.cod_imovel as cod7_11_0_,
        this_.descricao as descricao11_0_,
        this_.dt_inclusao as dt9_11_0_,
        this_.endereco as endereco11_0_,
        this_.estado as estado11_0_,
        this_.medida as medida11_0_,
        this_.pais as pais11_0_,
        this_.status as status11_0_,
        this_.titulo as titulo11_0_,
        this_.valor as valor11_0_ 
    from
        Imovel this_ 
    where
        this_.bairro ilike ? 
        and this_.cidade ilike ? 
        and this_.estado ilike ? 
        and this_.valor between ? and ?
17:34:18,111 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor OutjectResult
17:34:18,111 DEBUG [OutjectResult       ] outjecting imovelList=[]
17:34:18,115 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ForwardToDefaultViewInterceptor
17:34:18,115 DEBUG [ForwardToDefaultViewInterceptor] forwarding to the dafault page for this logic
17:34:18,121 DEBUG [DefaultPageResult   ] forwarding to /WEB-INF/jsp/index/busca.jsp
17:34:18,121 DEBUG [DefaultStaticContentHandler] Deferring request to container: /imobiliaria/WEB-INF/jsp/index/busca.jsp 
17:34:18,125 DEBUG [VRaptor             ] VRaptor ended the request
17:34:18,207 DEBUG [VRaptor             ] VRaptor received a new request
17:34:18,216 DEBUG [DefaultRequestExecution] executing stack  DefaultRequestExecution
17:34:18,259 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ResourceLookupInterceptor
17:34:18,260 DEBUG [DefaultResourceTranslator] trying to access /imagens/aplication/menu_div.jpg
17:34:18,260 DEBUG [VRaptor             ] VRaptor ended the request

Alguém sabe como poderia preencher apenas um dos campos e obter resultados?
Abraço!

Guevara, creio que o problema é que como os parâmetros valorMin e valorMax são passados como null, a consulta vai ficar between null and null e não vai retornar nada mesmo, as solução é fazer um if que testa se as duas variáveis não são nulas e só então adiciona a restrição, assim:

if (valorMin!=null & valorMax!=null)
{
criteria.add(Restrictions.between(“valor”, valorMin, valorMax)) ;
}

vale lembrar que o mesmo erro poderá ocorrer com os demais parâmetros, se vierem como null, no caso deverão ser feitos outros if’s.

Obrigado pela dica mrrbigu, fiz aqui as modificações, mas agora o problema é o inverso, só de chamar o método de busca ele lista todos os imóveis do banco, mesmo que eu não preencha nenhum campo, se eu pesquisar em apenas um campo a busca funciona:

public List<Imovel> busca(String bairro, String cidade, String estado, BigDecimal valorMin, BigDecimal valorMax) {
		Criteria c = session.createCriteria(Imovel.class);
		if (bairro != null) {		
	    c.add(Restrictions.ilike("bairro", bairro, MatchMode.ANYWHERE));
		}
	    if (cidade != null) {
	    c.add(Restrictions.ilike("cidade", cidade, MatchMode.ANYWHERE));
	    }
	    if (estado != null) {
	    c.add(Restrictions.ilike("estado", estado, MatchMode.ANYWHERE));
	    }
	    if (valorMin != null & valorMax != null) {
	    c.add(Restrictions.between("valor", valorMin, valorMax));
	    }
	    return c.list();
	}
	

Abraço!

Conversando com o Bronx, ele me alertou quanto aos if’s, está listando tudo pq ao chamar o método de busca os campos estão vazios e estando vazios os if’s são ignorados, o método roda apenas o return c.list(); fazendo que liste td que está no banco.

sim, ele vai listar pq vc tem la um c.list como retorno, eh o mesmo que from nome_classe; uma vez que se todas as suas condicoes if for false. Outro detalhe, dar uma pesquisa, o Criteria tem metodos especificos para trabalhar com null, nao dar para querer tratar alguns pontos do criteria como fazemos com o java. pesquisa no livro beginning hibernate da apress no capitulo 9 eu acho, e vc vai encontrar tudo que precisa sobre o criteria e resolver seus problemas em questao de minutos.

Obrigado LPJava, vou pesquisar em outra fonte, no manual do Hibernate não achei ainda a resposta.
Abraço!

[quote=Guevara]Obrigado LPJava, vou pesquisar em outra fonte, no manual do Hibernate não achei ainda a resposta.
Abraço![/quote]

no livro que ti falei tem, e vc sabe onde encontra -lo na web hehhe.

flw “4you”

Achei o livro pra download, vou ler aqui e assim que conseguir resolver eu posto aqui. Valeu!

Guevara, se você faz uma pesquisa no banco e não pede nenhum filtro, para mim é normal que venham todos os registros, se vocês espera um filtro padrão para quando os demais são nulos, é só criar uma condição para isso.

Resolvi.
Vc está certo mrrbigu, o método retorna automáticamente os objetos, eu não sabia desse detalhe, outro detalhe é que eu estava usando uma página só para busca e visualização dos resultados, por isso ao carregar a página os resultados vinham automáticamente. Para resolver esse problema, eu separei, criei uma página busca.jsp para efetuar a busca e uma página resultado.jsp para visualizar a pesquisa.
O livro que o LPJava recomendou é muito bom, melhor que o manual do Hibernate com aqueles exemplos dos “gatos” que estavam enchendo o saco.
Testei vários métodos de busca e estes dois funcionam na boa:

Criteria c = session.createCriteria(Imovel.class);		
		if (bairro != null) {		
	    c.add(Restrictions.ilike("bairro", bairro, MatchMode.ANYWHERE));
		}
		if (cidade != null) {
	    c.add(Restrictions.ilike("cidade", cidade, MatchMode.ANYWHERE));
	    }
		if (estado != null) {
	    c.add(Restrictions.ilike("estado", estado, MatchMode.ANYWHERE));
	    }
		if (valorMin != null & valorMax != null) {
	    c.add(Restrictions.between("valor", valorMin, valorMax));
	    }
	    List results = c.list();
		return results;

Ou, usando Disjunction, capítulo 10, página 216 do livro Beginning Hibernate - Apress.

Criteria crit = session.createCriteria(Imovel.class);
		Criterion bai = Restrictions.ilike("bairro", bairro, MatchMode.ANYWHERE);
		Criterion cid = Restrictions.ilike("cidade", cidade, MatchMode.ANYWHERE);
		Criterion est = Restrictions.ilike("estado", estado, MatchMode.ANYWHERE);
		Criterion val = Restrictions.between("valor", valorMin, valorMax);
		Disjunction disjunction = Restrictions.disjunction();
		if (bairro != null && !bairro.isEmpty())
			disjunction.add(bai);
		if (cidade != null && !cidade.isEmpty())
			disjunction.add(cid);
		if (estado != null && !estado.isEmpty())
			disjunction.add(est);
		if (valorMin != null && valorMax != null)
			disjunction.add(val);
		crit.add(disjunction);
		List results = crit.list();
		return results;

Os if’s foram sugeridos pelo colega Bronx daqui do fórum, pois sem eles, qualquer campo preenchido o método retorna todo o conteúdo do banco, assim como o primeiro método postado.
Obrigado pela atenção!
Abraço!!