Consulta específica no hibernate [RESOLVIDO]

11 respostas
V

Olá pessoal,
estou com um problema aqui ta dificil deu conseguir resolver, o problema é em uma consulta que envolve duas tabelas, a consulta funciona normal, o problema é na hora de fazer o cast eu nao consigo pegar o resultado da consulta para exibir em uma JTable, vo cola parte do codigo abaixo para dar pra enterder melhor:

A Consulta:
hql = "from Compras c, Pjuridicas p  where c.pessoas.pesCodigo = p. jurCodigo and p.jurFantasia like '%'";

A consulta é esta acima que evolvendo duas tabelas que são Compras e Pjuridicas, ela funciona por ja testei.

O Cast:
Compras actor;
        Pjuridicas pes;
        for(Object o : resultList) {
//O Problema acontece aqui na linha abaixo
            actor = (Compras)o;

            pes = (Pjuridicas) sessao.get(Pjuridicas.class, actor.getPessoas().getPesCodigo());
            Vector<Object> oneRow  = new Vector<Object>();
            oneRow.add(actor.getComCodigo());
            oneRow.add(pes.getJurFantasia());
            oneRow.add("R$"+formatarFloat(Float.parseFloat(actor.getComVlrtotal().toString())));
            oneRow.add(new SimpleDateFormat("dd/MM/yyyy").format(actor.getComData()));

            if (actor.getComFormapagto()=='1'){
                oneRow.add("À Vista");
            }else{
                oneRow.add("À Prazo");
            }
            
            modelo.addRow(oneRow);
       }

Bom eu ja sei que eu nao poderia estar tentando converte o resultado dessa consulta em compras pq tem 2 tabelas, o problema é que eu nao sei como resolver isso
Gostaria de saber se tem algum modo de se resolver esse problema como eu pego o resultado dessa consulta para poder colocar na minha JTable???

O Exeption que retorna:
Exception occurred during event dispatching:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to hibernate.entity.Compras
        at movimentacoes.dlgCompras.displayResult(dlgCompras.java:220)
        at movimentacoes.dlgCompras.busca(dlgCompras.java:685)

11 Respostas

L

A sua consulta vai retornar um Object[] com um Compra na posicao 0 e um Pjuridicas na posicao 1
tente fazer assim:

for(Object[] o : resultList) { 
actor = ((Compras) o[0] );
pes =((Pjuridicas )o[1]);
}
M

Fala ai Vinny,

Geralmente não trabalho com hql da mesma maneira que voce esta trabalhando.
HQL != SQL

HQL = É a fusão entre o SQL com alguns recursos do Hibernate !

Sendo assim, acredito que é legal abusar desses recursos
Por exemplo se precisar fazer oque voce esta precisando faria assim !

no meu modelo/entity acrescentava um construtor que recebe os parametros que estão vindo do SQL

public class Funcionario {
  private String nome;
  private String senha;
  private Acesso acesso;

  public Funcionario(){}

  public Funcionario(String nome, String senha){
     this.nome = nome;
     this.senha = senha;
  }
}

Na hora de criar o hql EU criaria ele assim !

public List<Funcionario> consultar(){
  String query = "SELECT com.modelo.Usuario(usuario.nome, usuario.senha) FROM usuario WHERE usuario.nome=:nome";
  Criteria hql = session.createQuery(query);
  hql.setParamter("nome", "magno");

  return hql.list;
}

Repare na linha :

String query = "SELECT new com.modelo.Usuario(usuario.nome, usuario.senha) FROM usuario WHERE usuario.nome=:nome";

Eu seleciono os campos no SQL e automaticamente instancio a classe usuario passando como parametro o nome e a senha.
Pronto nem faço um loop pra trabalhar em cima do result o hibernate ja faz td isso automaticamente !

Outro detalhe importante é a auxencia de Joins !
Se ouver relacionamentos entre classes no HQL posse pode fazer assim

String query = "SELECT new com.modelo.Compras(compras.pessoas.pesCodigo, compras.pjuridicas.jurFantasia) FROM compras ";

Voce vai andando pelos relacionamentos como se fosse java e o Hibernate se encarrega de realizar os Joins necessários !

Ajudou ???

FUIIII !!!

V

LGWEB
eu tentei usar o seu exemplo mais nao deu certo dá tipos imcopatíveis

for(Object[] o : resultList) { ...}

MAGNOCOSTA
Vi seu exemplo e eu realmente não sabia que podia fazer isso, ainda so meio leigo em hibernate, mas eu nao intendi o que é o com.modelo.NomeDaEntidade
da onde vem o com e o modelo?

eu fui tentar usar mais empaquei nisso

L

Vinny:
LGWEB
eu tentei usar o seu exemplo mais nao deu certo dá tipos imcopatíveis

for(Object[] o : resultList) { ...}

MAGNOCOSTA
Vi seu exemplo e eu realmente não sabia que podia fazer isso, ainda so meio leigo em hibernate, mas eu nao intendi o que é o com.modelo.NomeDaEntidade
da onde vem o com e o modelo?

eu fui tentar usar mais empaquei nisso

É o endereço completo do seu objeto.
Assim ele consegue instanciar.
Exemplo:
br.com.teste.model.pessoa

L

Achei um tópico que tinha escrevido (soa estranho, mas escrevido é correto) soa aqui no wiki da empresa…
Título: Fugindo do proxy do hibernate:

Não quer restaurar a árvore de objetos do hibernate?
Quer resgatar somente os principais dados do banco?

Use ConstructionExpression…

Tenha um construtor no seu objeto com os mesmos parametros de consulta, assim o jpa instância seu objeto e passa os valores como argumento.

Ex…

Objeto / Construtor

public PublisherInfo(Long id, String revenue, Double price){
     this.field = id...
}

** Cuidado com os tipos declarados, pois se a sequencia estiver errada ou os tipos de dados forem diferentes o jpa não conseguirá instânciar seu objeto.

Query…

SELECT NEW com.company.PublisherInfo(pub.id, pub.revenue, mag.price) FROM Publisher pub JOIN pub.magazines mag WHERE mag.price > 5.00
return (List<PublisherInfo>) query.getResultList();

Perfeito para apresentação na tela, otimizações de consultas e relatórios.

** Não persista este objeto!

Link.
http://download.oracle.com/docs/cd/E11035_01/kodo41/full/html/ejb3_langref.html#ejb3_langref_constructor

Abs

M

Conforme a galera acima já respondeu Vinny essa classe é do seu projeto.
vc não tem uma classe Pjuridicas no seu projeto?
então usa ela !

entendeu ?

V

Ahan entendi a parte dos pacotes, agora vou colocar em pratica agradeço a ajuda de vcs.

Vlw galera!!

L

Lembrando que se vc estiver usando hibernate direto, sem jpa, é melhor vc usar desta forma.

query.setResultTransformer(Transformers.aliasToBean(ModelRazao.class));

Assim vc não necessitará ter construtor nem nada.

Agora se o seu arquiteto fala que vc não pode usar coisas específicas do seu provedor de persistência, e
que vc tem que se ater a especificação (JPA), use construction expression. (Desabafei!!!)
rsrsrs

Muda o título do tópico…
Além de acrescentar [RESOLVIDO], coloca algo mais coerente com o contexto :slight_smile:

Acredito que algo similar a “Como fugir do proxy do hibernate [RESOLVIDO]” ou “Consulta específica no hibernate [RESOLVIDO]” ficaria interessante.

V

Mudei o titulo do tópico

To vendo que esse negocio de hibernate é bem flexivel, tem varias maneira de fazer a mesma coisa.
obrigado por mais uma dica.

V

Bom, desculpa mais ainda não posso dizer que ta resolvido, pq ta foda, eu nao uso JPA somente hibernate, descobri isso quando fui tentar fazer isso pra testa:

Collection collection = sessao .createCriteria(hibernate.entity.Produtos.class, "p") .setProjection( Projections.projectionList() .add( Projections.property("p.proCodigo").as("codigo") ) .add( Projections.property("p.proDescricao").as("nome") ) ) .setResultTransformer(new AliasToBeanResultTransformer(Produtos.class)) .list();

ai retornou esse exception:

org.hibernate.PropertyNotFoundException: Could not find setter for codigo on class hibernate.entity.Produtos at org.hibernate.property.ChainedPropertyAccessor.getSetter(ChainedPropertyAccessor.java:44) at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:57) at org.hibernate.loader.criteria.CriteriaLoader.getResultColumnOrRow(CriteriaLoader.java:115) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:606) at org.hibernate.loader.Loader.doQuery(Loader.java:701) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236) at org.hibernate.loader.Loader.doList(Loader.java:2220) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104) at org.hibernate.loader.Loader.list(Loader.java:2099) at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94) at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569) at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283) at cadastros.dlgProdutos.txtChaveCaretUpdate(dlgProdutos.java:856)

não tem outra forma de resolver isso sem usar JPA, somente com hibernate?

eu tava tentando do jeito que o lgweb mas nao funciona
eu nao consigo acessa o array do object, no codigo quando eu coloca Object[] o : resultList ja fica grifado de vermelho então nem da pra rodar!

Quando eu faço a consulta que eu citei mas acima retorna o Object assim

Nome----------------Tipo
o[0]------------------Compras
o[1]------------------Pjuridicas

tem alguma outra forma de acessar isso?
pq assim

Compras com = (Compras) o[0];
não funciona.

V

Bom consegui axar um jeito via HQL para resolver, minha consulta so vai retornar a tabela que preciso.

ficou assim:

hql = "from Compras c " + " where pessoas.pesCodigo in (select jurCodigo from Pjuridicas " + " where jurFantasia like '%"+ txtChave.getText().toUpperCase()+"%') ";
era assim:

Criado 12 de agosto de 2010
Ultima resposta 15 de ago. de 2010
Respostas 11
Participantes 4