Fugindo do Eager: LazyCollection + Statefull + set.contains("")

14 respostas
rodrigoy

Fala aí mestres…

Olha só a seguinte situação<hipotética>.

Tenho uma classe Turma que contém um Set<Aluno> com FetchType.LAZY (tem que ser Lazy por questões de performance).

Então, tenho uma TelaDeTurma que exibe dados da turma mais os alunos da turma.

Para essa tela (que é Swing) tenho um Facade @Stateful:

@Stateful
public class TurmaFacadeBean implements TurmaFacade {

   private Turma turma;

   @PersistenceContext  
   private EntityManager manager;

   public Turma obter(Long id) {
      this.turma = manager.find(Turma.class, id);
      return turma;
   }

   public Set&lt;Aluno&gt; getAluno() {
      this.turma.getAluno().contains(""); //preciso disso para inicializar a coleção
      return this.turma.getAluno();
   }
}

Pergunta 1: Esse contains("") é a coisa mais feia que já coloquei no código, mas sem ele não inicializa a coleção! Tem alguma outra alternativa?

Pergunta 2: Qual a diferença de getReference e find no EntityManager?

Abraços!
Rodrigo Y.

14 Respostas

F

Rodrigo,

Deixa eu ver se entendi.
Tu tem uma tela que “usa” este facade para pegar os dados. Se tu nao inicializa a colecao a mesma da dando LazyIni…Exception?

É por isso que tu ta dando o contains()?

Bom nao sei se entendi certo, mas se for isso tem outra maneira de inicializar a colecao que seria utilizando o Hibernate.initialize(), mas IMHO é igualmente horrivel fazer isso.

Outra maneira, que eu acho mais “bonita”. Se tu estiver usando Hibernate com Criteria tu pode usar o setFethMode da API e usar um metodo de Feth diferente para essa consulta.

Se nao entendi bem, passa mais detalhes ai.

]['s

rodrigoy

É isso mesmoo contains("") é só para não dar LazyLoadException no cliente remoto… O negócio é que estou baseando tudo no entity manager, e não no hibernate…

Como assim Hibernate.initialize? Como assim com criteria?

(Turma e Alunos é uma agregação).

F

Acho que eu precipitei as coisas suponhando que tu estaria usando Hibernate no JPA. :smiley:

Vamos la. Qual a implementacao de JPA que tu ta usando?

O que eu quiz dizer é o seguinte. Com JPA puro acho que nao tem como fazedr isso.
Se a tua implementacao for o Hibernate da pra usar esse “recurso” dele (Hibernate.initialize()) ou ainda nao usar os relacionamentos como tu ta fazendo e forcar uma consulta com Criteria. Claro tudo isso vai te deixar dependente da implementacao que estiver usando.

Agora com JPA puro, como nao tem api de Criteria acho que nao tem muita solucao.

]['s

rodrigoy

fabgp2001:
Vamos la. Qual a implementacao de JPA que tu ta usando?

É Hibernate, mas não quero nem saber se for outro… :slight_smile:

fabgp2001:
Se a tua implementacao for o Hibernate da pra usar esse “recurso” dele (Hibernate.initialize())

Acho que vou criar uma classe “WorkAroundUtils”… mas realmente não sabia desse “Hibernate.initialize(Object proxy)”. Valeu!!!

Epa, não estou disposto a mudar o meu modelo de negócio só por conta desse contains("")…

Cliente desconectado: O buraco é mais embaixo… :frowning:

F

rodrigoy:
Cliente desconectado: O buraco é mais embaixo… :frowning:

Pois é tambem acho.

Ja rolou uma discucao aqui no GUJ do pessoal falando do JPA nao ter uma API de Criteria. Se tivesse o problema poderia ser resolvido facilmente.

]['s

A

Criteria API seria legal, mas dá para fazer uma busca mudando o tipo de carregamento do relacionamento usando JPQL. Veja a documentação dos FETCH JOINs.

rodrigoy

As coisas estão melhorando, mas o paradigma OO atual ainda tem muitas limitações… concordam?

:cry:

plentz

rodrigoy:
As coisas estão melhorando, mas o paradigma OO atual ainda tem muitas limitações… concordam?

:cry:

Er, exemplifique as limitações que o “paradigma OO” tem?

Proteu_Alcebidiano

rodrigoy:
As coisas estão melhorando, mas o paradigma OO atual ainda tem muitas limitações… concordam?

:cry:

hum, você quis dizer limitações na implementação do paradigma no design de uma linguagem, não? :wink:

rodrigoy

Discuti um pouco sobre algumas coisas nesse post:

http://www.guj.com.br/posts/list/47179.java

Proteu, estou me limitando ao Java mesmo, mas creio que para qualquer linguagem/arquitetura o modelo de objetos ainda é um pouco longe do negócio.

Por exemplo, o post que mencionei diz que os entities no EJB 3.0 já podem sair livremente para a camada de apresentação, porém, não é a mesma coisa do que se tivesse no servidor. (Alguma linguagem ou arquitetura resolve isso de uma maneira melhor?)

É confuso, ao mesmo tempo que as coisas evoluem e ficam mais simples parece que mais e mais “workarounds” vão surgindo…

Não sei se estou sendo claro… a meu ver a informática vai começar a ficar legal quando não precisarmos mais do departamento de informática…

Paulo_Silveira

ejb2! os entity beans funcionavam remotamente, ja que eles nao ficavam detached nunca, sempre acessados atraves de seus stubs. mas ai tinha o problema de zilhares de chamadas remotas, entao criaram as interfaces locais. ai quando viram que a boa pratica seria SEMPRE usar interface local para os EBs, criaram o ejb3 de tal maneira q eles nao podem ser acessados como um EB managed de fora do servidor.

em outras palavras: a boa pratica virou spec

rodrigoy

Até gostava dessa característica dos EBs 2.1, mas não ao custo da complexidade que é trabalhar na espec EJB 2… não vale a pena por conta da baixa produtividade.

Essa prática dos EBs só terem interface local que alastrou DTOS por tudo quando é sistema…

falous!

Fabio_Kung

É isso mesmo Rodrigo. Não tem jeito.

Mas não acho que a limitação aí seja da OO não. A limitação é justamente o cliente remoto. Como envolve a rede, o uso da banda tem que ser sempre otimizado, transmitindo só o que for necessário.

Por isso sim, você precisa iniciar a coleção de alguma forma. Mesmo que seja com o contains.

Estamos longe de ter transparência total pra aplicações distribuídas.

Em tempo: eu já acho essa história de dividir interface local e remota muito estranha. O ejb contêiner tinha de ser esperto o suficiente para saber quando acessar um ejb remoto ou local, não acham?

mchiareli

como inicializar o proxy criado pela jpa, antes de enviar para o cliente, estou com problemas neste ponto, ele envia o objeto “falso” então gera exceptions malucas…

nao acho nada disso relacionado a jpa, apenas a coisas especificas como hibernate ou spring-jpa, não é possivel fazer isso com jpa, eu preciso desligar o lazy loading no persistence.xml…??

Criado 28 de novembro de 2006
Ultima resposta 24 de ago. de 2007
Respostas 14
Participantes 8