Trazer valor dataField (Flex + Java + Hibernate)

Galera estou começando com Flex e estou com o seguinte problema…
Tenho uma classe Venda que TEM-UM Regiao. Estou tentando trazer em um dataGrid/dataField o descritivo da Região (Ex.: Id_Venda: 1 - Regiao: Sudeste), mas não estou conseguindo a Regiao, esta retornando NULL.
Obs.: O Id retorno normalmente.

// *********** CLASSES JAVA **********
@Entity
@Table(name = "VENDA")
public class Venda {
	@Id
	@Column(name = "ID_VENDA")
	private Integer id;

	@ManyToOne
	@JoinColumn(name = "ID_REGIAO")
	private Regiao regiao;
	
	//getters e setters
}

@Entity
@Table(name = "REGIAO")
public class Regiao {
	@Id
	@Column(name = "ID_REGIAO")
	private Integer id;
	
	@Column(name = "REG_DESC")
	private String nome;
	
	//getters e setters
}

public class VendaHibernate {
	...
	public Collection<Venda> obterVendas() {		
		
		Session session = ConnectionFactory.getConnectionHibernate();
		String hql =  "select venda from Venda as venda  inner join venda.regiao as regiao";		
		Query query = session.createQuery(hql);
		query.setMaxResults(10);
		return query.list();
}

// *********** ACTION  SCRIPT **********
package br.srv.work.flex.model
{
	[RemoteClass(alias="br.srv.work.model.Venda")]

	[Bindable]    
	public class Venda{
		public var id:int;
		public var quantidade:Number;
		public var valor:Number;
		public var regiao:Regiao;
	}
}

package br.srv.work.flex.model
{
	[RemoteClass(alias="br.srv.work.model.Regiao")]

	[Bindable]    
	public class Regiao{
		public var id:int;
		public var nome:String;
	}
}

// *********** VIEW - mxml**********
// Trecho do código do dataGrid
...
<mx:AdvancedDataGrid id="grdVenda" designViewDataType="tree" width="100%" height="100%" selectionMode="none" dataProvider="{vetorDadosVenda}">
	<mx:columns>
		<mx:AdvancedDataGridColumn headerText="Id" dataField="id"/> //AQUI O CONTEUDO É RETORNADO NORMALMENTE
		<mx:AdvancedDataGridColumn headerText="Regiao" dataField="regiao.nome"/> //AQUI NÃO RETORNA NADA
</mx:AdvancedDataGrid>

Alguma sugestão :?:

Valeu!!!

O DataGrid não funciona do jeito que vc colocou

o datafiled não pode incluir o ponto, ele não “navega” no seu objeto. O que vc pode fazer é setar uma labelFunction nessa coluna.

Precisando, de uma olhada nos cursos da Nuccitec.

[]s

Oi arsinfo,

Então, isto está acontecendo provavelmente por causa do lazy loading do hibernate. Quando você está do lado Java, o hibernate mantem o objeto “vivo” e quando você pede algum atributo dele que faz referência a alguma outra tabela, ele carrega esse objeto sob demanda.

Quando você serializa esse objeto mais externo via AMF, o Hibernate não tem tempo de carregar o objeto que compõe o outro objeto, pq afinal você não pediu isso (ao tentar acessar o atributo), sendo assim, vem null.

Infelizmente, o BlazeDS (acredito que você esteja utilizando ele) não suporta o lazy loading do Hibernate, sendo assim, você tem que trazer tudo de uma vez, ou seja, o objeto e todas as suas dependências. Apesar de não recomendado, você deve mudar a estratégia de carga do hibernate no relacionamento para EAGER.

Para fazer isso, nas anotações que correspondem aos relacionamentos entre as entidades, basta vc informar o fetch como EAGER:

@ManyToOne( fetch = FetchType.EAGER ) @JoinColumn(name = "ID_REGIAO") private Regiao regiao;
Isso pode inpactar negativamente no desempenho do seu sistema e eu infelizmente não sei como contornar isso usando o BlazeDS. Não sei tbm se é possível contornar porque nunca fiz nenhum projeto “de verdade” usando o BlazeDS.

[]´s

[quote=renzonuccitelli]O DataGrid não funciona do jeito que vc colocou

o datafiled não pode incluir o ponto, ele não “navega” no seu objeto. O que vc pode fazer é setar uma labelFunction nessa coluna. [/quote]

Tem certeza Renzo? Eu faço assim e não tenho problema algum.

Falha minha…hehe.

Testei e funfou com propriedade aninhada, dessa eu não sabia.

Achei que não seria o problema de lazy pq se fosse, ele receberia uma exceção em vez de apenas a propriedade região nula…

[quote=renzonuccitelli] Falha minha…hehe.

Testei e funfou com propriedade aninhada, dessa eu não sabia.

Achei que não seria o problema de lazy pq se fosse, ele receberia uma exceção em vez de apenas a propriedade região nula…[/quote]

:smiley:

Então, como eu falei, eu ainda não usei hibernate + blazeds pq não precisei, então eu agora que não sabia sobre a excessão. Mas me parece estranho disparar uma excessão pq vem um objeto apontanto para null. Tem certeza disso tbm? Depois vou testar.

[]´s

Isso é certeza sim, é um problema bem conhecido e até tem tópico aqui no GUJ. Parece que o cara do StackOverFlow passou pelo mesmo problema do autor do tópico.
Dá uma olhada pra ver se ajuda.

[]s

[quote=renzonuccitelli] Isso é certeza sim, é um problema bem conhecido e até tem tópico aqui no GUJ. Parece que o cara do StackOverFlow passou pelo mesmo problema do autor do tópico.
Dá uma olhada pra ver se ajuda.

[]s[/quote]

Não sabia :slight_smile:
Como nunca tinha feito, então não sabia. Obrigado pelo link :wink:

[]´s

davidbuzatto

Mesmo utilizando EAGER não esta trazendo os dados, vc tem alguma idéia do que possa ser?

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "ID_REGIAO")
private Regiao regiao;

Vc leu o link do StackOverflow que enviei?

Li o artigo, mas até agora não consegui resolver.

Renzo, você comentou acima que funcionou, certo? Como vc fez?

O que funcionou foi o DataGrid pegar a propriedade aninhada.

Vc chegou a debugar pra pelo menos descobrir onde é o Problema? debugue seu serviço remoto pra ver se ele está construindo o objeto de forma correta. Sendo a construção correta, debug o retorno da chamada remota pra descobrir se o BlazeDS está serializando direito.


@Entity  
@Table(name = "VENDA")  
public class Venda {  
    @Id  
    @Column(name = "ID_VENDA")  
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;  
  
    @ManyToOne  
    @JoinColumn(name = "ID_REGIAO")  
    private Regiao regiao;  
      
    //getters e setters  
}  
  
@Entity  
@Table(name = "REGIAO")  
public class Regiao {  
    @Id  
    @Column(name = "ID_REGIAO")  
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;  
      
    @Column(name = "REG_DESC")  
    private String nome;  
      
    //getters e setters  
}  

Não deu pra testar mais até aqui, acho que está tudo ok.
Agora no seu HQL.


  public List<Venda> obterVendas() {        
          
        Session session = ConnectionFactory.getConnectionHibernate();  
        Query query = session.createQuery("select v from Venda v");  
        query.setMaxResults(10);  
        List<Venda> list = query.list();  //coloca um breakpoint e confere se o resultado está chegando aqui.
        return list;
   }

Para usar um objeto composto em um DataGrid, assunto que já está batido no forum.

<mx:DataGridColumn id="colunaRegiao" 
            labelFunction="labelFunctionRegiao" width="200"/>

 private function labelFunctionRegiao(row:Object, column:DataGridColumn):String
  {
         var regiao:Regiao = row as Regiao;
         return regiao.nome;
 }

Espero ter ajudado

Bruno, muito obrigado pela dica… Funcionou com algumas alterações:

private function labelFunctionRegiao(row:Object, column:AdvancedDataGridColumn):String {  
	var venda:Venda = row as Venda;		
	return venda.regiao.nome;
}

Valeu!!!