Hibernate + Criteria + Flex [RESOLVIDO]

Bom pessoal… estou quebrando a cabeça a alguns dias pra fazer essa bagaça funcionar… já pesquisei e vi em vários lugares porém não me agradei com os resultados…

tenho a seguinte situação.

[code] public List getResumoSchema() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
EntityManager em = emf.createEntityManager();
Session session;

	session = (Session) em.getDelegate(); 

	ArrayList<Resumoschema> resumoSchemas = (ArrayList<Resumoschema>)session
	.createCriteria(Resumoschema.class)
    	.setProjection( Projections.projectionList()
    			.add( Projections.sum("tamanho").as("tamanho")) //summary
    			.add( Projections.groupProperty("esquema").as("esquema")) //agrupando
    			.add( Projections.groupProperty("data_informacao").as("data_informacao")) //agrupando
    	)
    	.addOrder(Order.asc("data_informacao")) //order by
    	.addOrder(Order.asc("esquema")) //order by
    	.list();

	return resumoSchemas;
}[/code]

Vejam que estou forçando e reforçando a conversão pra arraylsit que no caso é o meu VO… porém ele so me retorna o Arraylist, que no caso é o genérico… gostaria de conseguir fazer essa conversão normalmente, mas só tenho encontrado a conversão via iterator, etc…

Preciso realizar essa conversão para que no Flex eu obtenha as informações… porém, lá, só chega vários arrays…

Neste outro exemplo

[code] public List getResumoSchema2() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
EntityManager em = emf.createEntityManager();
Query findAllQuery = em.createNamedQuery(“resumoschema.findAll”);
List resumoSchemas = findAllQuery.getResultList();

	return resumoSchemas;
}[/code]

o retorno volta como desejo, List

Obs. no primeiro exemplo eu já tentei por como List mas nada muda.

Alguém já passou por isso??

Você tem a sua entidade no Java e no Flex? Pode postar o código delas?

Java

[code]@Entity
@Table(name = “Resumoschema”, schema = “system”)
@NamedQueries( { @NamedQuery(name = “resumoschema.findAll”, query = “from Resumoschema”) })
/*

    • Represents the serial version of the entity.
      */
      public class Resumoschema {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = “resumoschemaId”)
    private Long resumoschemaId;
    @Basic
    @Column(name = “a”)
    private String a;
    @Basic
    @Column(name = “esquema”)
    private String esquema;
    @Basic
    @Column(name = “tamanho”)
    private Integer tamanho;
    @Basic
    @Column(name = “data_informacao”)
    private Date data_informacao;[/code]

Flex

[Bindable] [RemoteClass(alias="vo.Resumoschema")] public class Resumoschema { public function Resumoschema() { } private var _resumoschemaId:int; private var _a:String; private var _esquema:String; private var _tamanho:Number; private var _data_informacao:Date;

Ai vai… =)

Tente assim:

[code]public List getResumoSchema() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
EntityManager em = emf.createEntityManager();
Session session;

session = (Session) em.getDelegate();   

return session
.createCriteria(Resumoschema.class)
.setProjection( Projections.projectionList()
.add( Projections.sum(“tamanho”).as(“tamanho”)) //summary
.add( Projections.groupProperty(“esquema”).as(“esquema”)) //agrupando
.add( Projections.groupProperty(“data_informacao”).as(“data_informacao”)) //agrupando
)
.addOrder(Order.asc(“data_informacao”)) //order by
.addOrder(Order.asc(“esquema”)) //order by
.list();

} [/code]

Debugando o retorno do flex… temos isso…

resumoSchema = mx.collections.ArrayCollection (@8f65f81) [0] = Array (@15598af9) [1] = Array (@15598ee9) [2] = Array (@15598b31) [3] = Array (@15598c49) [4] = Array (@15598bd9) [5] = Array (@15598f21) [6] = Array (@15598ba1) [7] = Array (@15598a19) [8] = Array (@155987e9) [9] = Array (@15598821) [10] = Array (@155988c9) [11] = Array (@15598661) [12] = Array (@155985b9) [13] = Array (@15598549) [14] = Array (@15598f91) [15] = Array (@15598e41) [16] = Array (@15586041) [17] = Array (@15586079) [18] = Array (@155860b1) [19] = Array (@15586121) [20] = Array (@15586159) [21] = Array (@155860e9) [22] = Array (@15586191) dispatchResetEvent = true filterFunction = null length = 23 [0x17] list = mx.collections.ArrayList (@8ec1a81) sort = null source = Array (@15598a89) __model.funcionarios = <errors during evaluation> session = <errors during evaluation>

quando vou converter pra arraycollection, não consigo exibir no meu DG as informações… é como se não fosse possível o flex reconhecer a informação que veio… ele popula o DG mas nao exibe a informação…

Aqui está um exemplo de como deveria vir pra eu conseguir exibir…

resumoSchema = mx.collections.ArrayCollection (@6ef6f81) [0] = Object (@6f9da39) [1] = Object (@6f9da39) [2] = Object (@6f9da39) ... dispatchResetEvent = true filterFunction = null length = 110 [0x6e] list = mx.collections.ArrayList (@6e4ba81) sort = null source = Array (@6eff3f9) __model.funcionarios = <errors during evaluation> session = <errors during evaluation>

e quem retorna essa informação é o Hibernate, sem o criteria…

[code] public List getResumoSchema2() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
EntityManager em = emf.createEntityManager();
Query findAllQuery = em.createNamedQuery(“resumoschema.findAll”);
List resumoSchemas = findAllQuery.getResultList();

	return resumoSchemas;
}[/code]

A necessidade de usar o criteria é agrupar as informações… =//

Quando chega como Array quer dizer que alguma das entidades está errada, houve algum erro na deserialização ( não achou um objeto espelho no flex ou no java ).

Agora que vi com mais calma suas entidades já sei onde podem estar os erros.

  1. Sua classe no Java tem os getter’s e setter’s?
  2. Sua classe no AS deve ter propriedades como publicas ( se for private precisa dos getter’s e setter’s )
  3. O nome no AS deve ser igual ao Java

Existe mais códigos nessas entidades?

Rafael,

é justamente por isso que não estou entendendo nada… tenho uma rotina com hibernate e só… essa rotina funciona… tenho outra rotina com hibernate + criteria… essa da o galho que te falei…
o problema é que as duas rotinas usam as mesmas VO’s :shock:
Segue a classe completa

Flex

[code]package vo
{
[Bindable]
[RemoteClass(alias=“vo.Resumoschema”)]
public class Resumoschema
{
public function Resumoschema()
{
}
private var _resumoschemaId:int;
private var _a:String;
private var _esquema:String;
private var _tamanho:Number;
private var _data_informacao:Date;

	public function set resumoschemaId(resumoschemaId:int):void {
		_resumoschemaId = resumoschemaId;
	}
	
	public function get resumoschemaId():int {
		return _resumoschemaId;
	}

	public function set a(a:String):void {
		_a = a;
	}
	
	public function get a():String {
		return _a;
	}
	
	public function set esquema(esquema:String):void {
		_esquema = esquema;
	}
	
	public function get esquema():String {
		return _esquema;
	}
			
	public function set tamanho(tamanho:Number):void {
		_tamanho = tamanho;
	}
	
	public function get tamanho():Number {
		return _tamanho;
	}
	
	public function set data_informacao(data_informacao:Date):void {
		_data_informacao = data_informacao;
	}
	
	public function get data_informacao():Date{
		return _data_informacao;
	}
}

}[/code]

java

[code]package vo;

import java.util.Date;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

@Entity
@Table(name = “Resumoschema”, schema = “system”)
@NamedQueries( { @NamedQuery(name = “resumoschema.findAll”, query = “from Resumoschema”) })
/*

    • Represents the serial version of the entity.
      */
      public class Resumoschema {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = “resumoschemaId”)
    private Long resumoschemaId;
    @Basic
    @Column(name = “a”)
    private String a;
    @Basic
    @Column(name = “esquema”)
    private String esquema;
    @Basic
    @Column(name = “tamanho”)
    private Integer tamanho;
    @Basic
    @Column(name = “data_informacao”)
    private Date data_informacao;

    public String getA() {
    return a;
    }

    public void setA(String a) {
    this.a = a;
    }

    public String getEsquema() {
    return esquema;
    }

    public void setEsquema(String esquema) {
    this.esquema = esquema;
    }

    public Integer getTamanho() {
    return tamanho;
    }

    public void setTamanho(Integer tamanho) {
    this.tamanho = tamanho;
    }

    public Date getData_informacao() {
    return data_informacao;
    }

    public void setData_informacao(Date data_informacao) {
    this.data_informacao = data_informacao;
    }

    public Long getResumoschemaId() {
    return resumoschemaId;
    }

    public void setResumoschemaId(Long resumoschemaId) {
    this.resumoschemaId = resumoschemaId;
    }
    }
    [/code]

Tente isso:

Use o debug no java e verifique se o retorno dos dois métodos é o mesmo.É estranho mesmo essa situação.Eu uso tanto queries com Criteria como HQL e ambas o retorno chega correto.

Posta pra mim um exemplo seu…

Achei um teste que estava fazendo esses dias…

[code]public List teste(String id, String nome) throws FlexException {

this.session = HibernateUtil.openSession(id);
this.tx = this.session.beginTransaction();

Criteria c = this.session.createCriteria(Cliente.class);
c.add(Restrictions.like(“cli_nome”, “%” + nome + “%”));
c.setMaxResults(20);

return c.list();

}[/code]

Tente fazer uma criteria sem nenhum restrição para ver qual o retorno

o Criteria limpo funcionou…

[code] @SuppressWarnings(“unchecked”)
public List getResumoSchema11() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
EntityManager em = emf.createEntityManager();
Session session;

	session = (Session) em.getDelegate(); 
	Criteria c = session.createCriteria(Resumoschema.class);
	
	return c.list();
}[/code]

Tenta isso ai

  1. Retira o SUM do criteria e verifica se chega corretamente

  2. Debuga essa aplicação no Java, pois como você usa o SUM no criteria talvez essa lista esteja com objetos do tipo Double em vez do tipo Resumoschema.

Rafael, valeu muito pela ajuda e paciencia…

segue aí a solução para todas as nossas tentativas…

exemplo 1

public List<Resumoschema> getResumoSchema1() { EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); EntityManager em = emf.createEntityManager(); Session session; session = (Session) em.getDelegate(); String sql_query = " select resumo.esquema as esquema, " + " resumo.data_informacao as data_informacao, " + " sum(resumo.tamanho) as tamanho " + " from Resumoschema resumo " + " group by resumo.esquema, " + " resumo.data_informacao "; org.hibernate.Query query = session.createQuery(sql_query); query.setResultTransformer(Transformers.aliasToBean(Resumoschema.class)); List<Resumoschema> resumo = query.list(); return resumo; }

exemplo 2

	public List<Resumoschema> getResumoSchema2() {   
	    EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);   
	    EntityManager em = emf.createEntityManager();   
	    Session session;   
	  
	    session = (Session) em.getDelegate();   
	  
	  return session   
	    .createCriteria(Resumoschema.class)   
	        .setProjection( Projections.projectionList()   
	                .add( Projections.sum("tamanho").as("tamanho")) //summary   
	                .add( Projections.groupProperty("esquema").as("esquema")) //agrupando   
	                .add( Projections.groupProperty("data_informacao").as("data_informacao")) //agrupando   
	        )
	        .addOrder(Order.asc("data_informacao")) //order by   
	        .addOrder(Order.asc("esquema")) //order by
	        .setResultTransformer(new AliasToBeanResultTransformer(Resumoschema.class))
	        .list();   
	}  

a solução foi comer a documentação e achar esse bendito AliasToBean…
Ele vem em forma de array se a gente não fizer essa transformação… ou seja, formatar o resultado de acordo com os campos da classe que temos…

Fonte de pesquisa --> http://www.redhat.com/docs/en-US/JBoss_Hibernate/3.2.4.sp01.cp03/api/hibernate-core/org/hibernate/transform/AliasToBeanResultTransformer.html