segunda-feira, 29 de agosto de 2011

Instanciando um Bean em uma consulta HQL

Em uma consulta HQL quanto projetamos mais que um objeto, o mais comum é acessarmos a consulta por um List<Object[]> essa abordagem não é muito interessante, pois torna nossa consulta muito passível de dar erro, pois basta mudar a ordem das colunas e vamos causar um erro onde a consulta estiver sendo usada.


String hql = "select o.numeroProcesso, o.dataInicio from Processo o";
Query query = EntityUtil.createQuery(hql);
List<Object[]> list = query.getResultList();

Uma abordagem mais interessante é devolver essa consulta como um List<Map<String, Object>> criando os alias paras as colunas projetadas. Dessa maneira uma mudança de ordem na consulta não traria erro para quem a utilizasse:

String hql = "select new map(o.numeroProcesso as numeroProcesso, o.dataInicio as dataInicio) from Processo o";
Query query = EntityUtil.createQuery(hql);
List<Map<String, Object>> list = query.getResultList();
for (Map<String, Object> map : list) {
Object numeroProcesso = map.get("numeroProcesso");
}

A utilização do List<Map<String, Object>> é um avanço, mas pode induzir a erros de runtime, pois o cast fica sobre responsabilidade de quem for utilizar a lista.

Uma maneira mais segura é utilizar o recurso de instanciação do bean via construtor. O hibernate permite que instanciemos em nossa consulta uma classe que as colunas projetadas sejam passadas como parâmetro do construtor da classe:





Com essa abordagem, tornamos nossa consulta bem mais segura, pois vamos devolver uma lista com o nosso bean.



2 comentários:

Wesley disse...

Post muito instrutivo, parabéns.
Essa funcinalidade é tão útil que foi oficializada pelo JPA 2.0.
Deve-se lembrar apenas de passar os argumentos na exata ordem da declaração do construtor.

IronMan_br disse...

Valeu Wesley!!