Alguém usa algum padrão diferente de Open Session In View ao trabalhar com JPA?

E ae pessoal…bem, dando uma estudada cheguei a este post e mesmo já fazendo algum tempo que a discussão encerrou gostaria de deixar uma opnião minha.

Não sei se estou falando besteira, mas, acho muito limitado ter que definir se um relacionamento é lazy ou eager em tempo de compilação. Suponha que a entidade A tenha uma lista de entidades B, facilmente podemos nos deparar com uma situação onde num ponto da aplicação eu preciso consultar A, mas, nunca vou usar a lista de B’s…o que me levaria obviamente a escolha de Lazy, porém, em outro ponto é certo que todas as vezes que eu consulto A vou obter também sua lista de B’s, o que me faria escolher EAGER. Então, cada ponto da aplicação tem um comportamento específico, acho que deveria ser possível determinar esse comportamento em tempo de execução.

Eu evito muito usar hql’s, prefiro sempre o uso de Criteria, e talvez por isso me depare com esse problema, visto que com hql me parece que há essa possibilidade de mudar o comportamento em tempo de execução, mas, com criteria não vi isso ainda.

Fala Marlon!

Então cara, esta questão de trazer ou não os B’s(pegando o seu exemplo) pode ser resolvida no método que faz a consulta. Se em apenas alguns momentos você vai precisar dos B’s, você pode definir o seu atributo como LAZY e criar dois métodos: um que apenas faz a consulta(desta forma não traz os B’s) e outro que faz a consulta e, antes de a sessão ser fechada, inicializa sua lista(carrega os B’s).

Abraço.
Fica com Deus

1 curtida

Entendi sua sugestão Marcus, mas, continuo achando “ruim”, pois, dificulta criação de códigos genéricos…teria sempre de tá criando métodos.

Não consigo entender o problema, sendo que a definição de FetchType LAZY ou EAGER no mapeamento é para definir um padrão de comportamento.

É mais do que óbvio que se um objeto contém uma lista, uma hora ela será utilizada (ou pelo menos deveria), mas se ela for utilizada em 2 áreas do sistema, porém o objeto em outras 100, não faria sentido ela estar mapeada com FetchType EAGER, certo?

Agora se quiser alterar isso para inicializar a lista, existem diversas técnicas, incluindo as discutidas aqui nesse tópico. E quanto a sua dúvida de fazer um “JOIN FETCH” com Criteria do Hibernate, use o método createAlias

Digão,

É exatamente isso…eu acabei falando bobagem por não ter procurado antes…vlw!

Para o contexto JSF e JPA/Hibernate eu criei um componente chamado initializer no xpert-framework (que é open source).
O legal desse componente é você pode inicializar um relacionamento LAZY direto na view. Detalhes de como usar podem ser vistas no showcase do framework:

http://showcase.xpertsistemas.com.br/views/components/initializer.jsf

Exige um pouco só de configuração para utilizar o componente, mas no showcase tem exemplos.

[quote=marlon patrick]E ae pessoal…bem, dando uma estudada cheguei a este post e mesmo já fazendo algum tempo que a discussão encerrou gostaria de deixar uma opnião minha.

Não sei se estou falando besteira, mas, acho muito limitado ter que definir se um relacionamento é lazy ou eager em tempo de compilação. Suponha que a entidade A tenha uma lista de entidades B, facilmente podemos nos deparar com uma situação onde num ponto da aplicação eu preciso consultar A, mas, nunca vou usar a lista de B’s…o que me levaria obviamente a escolha de Lazy, porém, em outro ponto é certo que todas as vezes que eu consulto A vou obter também sua lista de B’s, o que me faria escolher EAGER. Então, cada ponto da aplicação tem um comportamento específico, acho que deveria ser possível determinar esse comportamento em tempo de execução.

Eu evito muito usar hql’s, prefiro sempre o uso de Criteria, e talvez por isso me depare com esse problema, visto que com hql me parece que há essa possibilidade de mudar o comportamento em tempo de execução, mas, com criteria não vi isso ainda. [/quote]

Você tem razão. É necessário definir query por query e não com uma instrução global como annotations por exemplo.
Sim, com isto significa criar vários métodos um para cada situação. É exactamente por isto que é necessário o padrão Repository. Ele serve para agrupar estes vários métodos. Por outro lado também resolve o problema do “opensessioninview” os dados que saem da camada de dominio devem ser detached. Isto em uma arquitetura onde o dominio é protegido e que em as camadas são independentes.

Por outro lado, dá para fazer as queries um pouco diferente para ter um pouco menos que métodos. Por exemplo, em vez de procurar por A e obter B, simplesmente procure pelos B que têm como pai A. Desta forma a hierarquia é mantida ( cada b ainda terá um A), mas não preciso de uma lista de B dentro de A que é o que causa o problema de ter que recarregar dados. Simplificar as entidades desta forma pode ser menos “orientado ao dominio” mas com a ajuda dos repositorios torna o processo mais simples. Por outro lado o uso de View Objects ( objetos que só existem na cada de view) pode ser outra forma para simplificar pois as queries não precisam ser feitas durante a renderização.