OPF - Cargas Automática de Relacionamentos

4 views
Skip to first unread message

Fabricio Colombo

unread,
Apr 6, 2009, 1:51:22 PM4/6/09
to infra...@googlegroups.com
Boa tarde,
 
estava conversando com o Marcos Barreto a respeito da carga automática de relacionamentos, mais ainda sem envolver a geração automática de sql.
 
vamos definir o objeto como sendo uma pessoa
 
IPessoa
  ID: IInfraInteger;
  Nome: IInfraString;
  Cidade: ICidade;
end;
 
A primeira opção é utilizar um segundo template para o relacionamento. A idéia é anotar no TypeInfo do atributo Cidade qual template utilizar para carregar o objeto relacionado, e durante o preenchimento do atributo, o framework verifica se o tipo de Relacionamento é carga automática, se for carga automática, efetuaria a carga baseada no join ou baseada em um outro template.
 
Só que isso resultaria em um select adicional para cada registro da tabela que representa IPessoa.
 
A segunda opção seria utilizar um Left Outer Join para carregar o relacionamento, de modo que apenas um select fosse executado. Para isso usariamos alias que seria a concatenacao da Classe + Propriedade, e nosso template ficaria assim:
 
Select a.ID, a.Nome, a.Id_Cidade Cidade_ID, b.Nome Cidade_Nome
  from Pessoa a
  left outer join Cidade b on b.Id = a.Id_Cidade
  Where a.ID = :ID
 
Ou utilizar a definição dos campos e tentar recuperar as informações pelo zeos.
 
Select Pessoa.ID, Pessoa.Nome, Pessoa.Id_Cidade, Cidade.Nome
  from Pessoa
  left outer join Cidade on Cidade.Id = Pessoa.Id_Cidade
  Where Pessoa.ID = :ID
 
Expressem suas opniões.
 
 
Fabricio
 

Solerman Kaplon

unread,
Apr 7, 2009, 8:01:10 AM4/7/09
to infra...@googlegroups.com
Fabricio Colombo escreveu:
Expressem suas opniões.

Acho que na primeira parte seria bom template separado, vai facilitar para testar uma possível implementação de lazy-loading. Ficaria um sql a mais, mas com lazy, só o faria se precisasse da informação. No hibernate é possível dizer qual o padrão de carga do relacionamento (lazy ou não) e se ele faz join ou não, tanto nas anotações qto na carga de objetos por criteria (ex: pode ter o padrão de ser lazy, mas em um caso especial dizer que quer um join).

Solerman

Marcos Barreto

unread,
Apr 7, 2009, 12:53:42 PM4/7/09
to infra...@googlegroups.com
Geralmente em relações 1-1 só necessitamos de algums dos atributos de um determinado objeto. ex:
Não tem por que eu carregar um objeto fornecedor completo sendo que na notafiscal eu preciso de pouquissimas informacões sobre o mesmo. ex: id e nome.

Fabricio fez um teste de carga usando um template com Join e a carga deu certo. ele só precisou por no alias dos atributos o seguinte:

select
   a.id,
   a.nome,
   a.idcidade "cidade.id",
   b.nome "cidade.nome"
from pessoa a
left outer join cidade b on (b.id = a.idcidade)
where a.id = :id

Vamos dizer que eu tenha:
p := TPessoa.Create
p.id := 10;
c := session.CreateNamedQuery('LoadPessoaByID', p);
p := c.GetResult as IPessoa

O InfraOPF hoje já carrega automaticamente os 2 atributos de cidade definidos no template para p.Cidade.

Só que, se por acaso tentar acessar qualquer outro atributo de cidade que nao seja id ou nome através de p.Cidade vai ter problemas por que vao estar nulos.

Eu estava pensando em marcar este objeto cidade como Proxy e nesta anotação definir o template de carga pelo oid. Então de alguma forma (usando aspectos eu acho), ao acessar um atributo null deste objeto proxy, carregariamos o objeto usando o template definido na anotação e removeriamos depois desta nova carga a anotação de proxy do mesmo. por que neste caso cidade já estaria completamente carregado.

Usar template separado pode ser custoso. por que imagine a situação:
1 nota, ligada a: 1 fornecedor, 1 transportadora e 20 items. Cada item ligado a seu produto. Se tivermos um template para cada teriamos a execução de 24 instruçòes SQL:
1 nota
1 fornecedor
1 transportadora
1 items
20 por causa dos produtos de cada cada item.
Reply all
Reply to author
Forward
0 new messages