Query Object

Alguém poderia me dar uma luz quanto a implementação do Query Object…
Exemplo: Os filtros do vem da minha tela (GWT), quando chega na camada de aplicação preciso transformar isso em Query Object / Criteria…
E depois transformar na camada de Infra (Hibernate) esse Query Object em Hibernate Criteria…Ta certo isso?
Ou faço direto nQuery Object algo que retorne os Criterias do Hibernate?

Me ajudem

O blog do Sérgio Taborda tem um artigo dissertando sobre esse padrão:

Abraços

Eu ja dei uma lida lá mais ainda nao entendi se devo fazer o QUery Object retornar os Criterias do Hibernate ou como devo fazer

Infelizmente ou felizmente preciso de um exemplo melhor ou mais completo

Você pode fazer as outras camadas lidarem com uma interface que possua os métodos desejados, atuando como uma Specification, e que é implementada por uma class que seja um QueryObject que possui um Hibernate Criteria.

//interface para negocios
interface BuscaUsuariosPorFaixaEtaria{
void setMinimo(int a);
void setMaximo(int a);
}

//persistencia
class BuscaUsuariosPorFaixaEtariaImpl implements BuscaUsuariosPorFaixaEtaria, QueryObjectHibernate{

private Criteria;

public BuscaUsuariosPorFaixaEtariaImpl(){
this.criteria = //new criteria
}

public void setMaximo(int a){
 //crietia.setParameterblablaba
}

public void setMinimo(int a){
 //crietia.setParameterblablaba
}

//usado na camada de ersistencia apenas
Query constroiQuery(){
return //criteria.toQuery()
}
}

Shoes e no caso de eu querer pegar por exemplo todos os meus usuarios cadastrados com o nome Lucas.
Faço uma specification pra isso tb? Se eu fizer no final das contas nao será a mesma coisa que criar um método de busca para cada consulta?

Só vale a pena usar esse padrão se sua consulta tiver alguma importância, se você for manipular o objeto que a representa de alguma forma ou se for utilizar polimorfismo. Mantêr o código extra pada uma consulta trivial não vale a pena.

Vai ter casos que vou utilizar consultas mais complexas, so que esses casos são dinâmicos, eu nunca sei como o cliente quer executar a busca, ele opcionalmente pode acidionar quantos filtros ele quiser. A pergunta é: Faço uma Specification generecia com claúsulas LIKE, IGUAL, MAIOR ou MENOR como? São essas operações que vou utilizar a princípio

QueryObject é qualquer objeto cujo estado define a pesquisa que vc quer fazer.
Vc pode criar QueryObject simples do tipo javabean em que seta alguns campos e pronto. Exemplo

UserQuery  uq = new UserQuery();

uq.setLogin("login');
uq.setActive(true);

User user = repository.findUser(uq);

Por vezes as pessoas se sentem tentadas a utilizar o proprio objeto de dominio ( user) para fazer este tipo de trabalho. Nesse caso o objeto de dominio assume tambem a responsabildiade de QueryObject e embora isso seja util a curto prazo não funciona sempre. O exemplo classico é procurar num intervalo de datas. O objeto de dominio só tem um campo data, logo não serve para esse propósito.

Vc pode criar QueryObjects mais complexos e mais genericos como que se fossem uma linguagem de pesquisa. Isso é o que o Hibernate faz com seus Criteria. Tudo depende do seu tempo, vontate, experiencia e paciencia.

Os QueryObjects podem servir em diversos niveis da aplicação. Vc pode utilizar-se deles para passar informações para o Repositorio. Nesse caso os QueryObjects são apenas de dominio. Ou seja, eles não contêm detalhes sobre persitencia ou algo assim. O repositorio irá interpretar esses dados e constuir a pesquisa para o DAO. Isso pode significa construir SQL ou outro tipo de QueryObject. Este parece ser o seu caso.

Nas classes de dominio vc cria o seu QueryObject e o popula com informações de pesquisa, o passa ao Repositorio. O reposiorio sabe que está usando hibernate e traduz esse QueryObject para um Criteria do Hibernate e o executa. O QeuryObject que foi enviado ao Repositorio tem total desconhecimento sobre o hibernate e seus criterias. Em opção o repositorio pode escrever HQL em vez de construir Criterias. O ponto é que o Repositorio tem que traduzir entre uns objetos e os outros. Aliás, é essa a sua função.

Com isto vc ganhar independencia do dominio, já que se mais tarde vc mudar para outro tipo de persistencia, (JPA por exemplo) vc terá que criar outro tipo deo objetos para executar as pesquisas, contudo seu repositorio continuará recebendo as mesmas informações e objetos e o seu dominio não muda uma virgula.

Muito obrigado Sergio, é exatamente isso que preciso fazer.
A unica coisa q vou ter q fazer a mais é q minha estrutura ficara assim:
GWT (Tela) -> Cria Filtros -> Camada Aplicação -> Gera Query Object -> InfraEstrutura -> Gera Criterias Hibernate