Problema com dependencia lazy

[quote=derlon][quote=garcia-jj]…Injeção de EJB no Vraptor não tem, o que você consegue fazer é usar um service locator (eu uso isso).
…[/quote]Usando EJB3 ou JPA é 1 prática comum injetar o @PersistenceContext na DAO (ou no Repository) => no caso do EJB, quando 1 atributo settado load=lazy é refenciado e o Objeto Entidade já está fora do Contexto EJB, o Hibernate (ou framework JPA) “sai de cena”. Uhm, …[/quote]

Vocẽ está confundindo as coisas. Service locator para buscar seus session beans, e não o persistence context e afins. Não há como injetar session beans em classes que não sejam controladas pelo container. No caso em servlets e backing beans você consegue injetar stateless-session-beans sem problemas.

[quote=derlon]@garcia-jj, tenho q concordar (em gênero, grau e número) com o Lucas quando ele diz: "a maioria das vezes o que vc tem que se perguntar é: vc precisa mesmo de EJB? seu sistema é distribuido? seu sitema tem clientes (outros sistemas) diferentes acessando o mesmo ejb?"
Digo isto pq: o EB3 sim fornece os mesmos recursos q o Spring fornece (e com a mesma simplicidade), mas por questões, como a descrita loga acima, temos sim q refletir muito antes de decidir adotar EJB 3: p/ex., 1 cenário simples, como o de LazyLoadExcecption, já obriga a usar o famigerado DTO (e, olha q neste caso, apenas para contornar o problema do ‘LazyLoadExcecption’).[/quote]

Derlon, sem querer causar flamewars, mas isso é pensamento de programador pequeno. EJB3 está longe de ser burocrático, e é até mais simples que usar Spring. Se você está com esse pensamento é porque realmente não conhece o suficiente de EJB. No caso do comentario que o Lucas fez me abstive de opinar porque pensei que o Lucas estava falando de EJB2, que aí sim eu concordo.

EJB não é apenas para aplicações distribuídas. Você pode facilmente trabalhar com aplicações simples usando EJB e ainda com performance melhor ainda que o Spring. Basta o programador saber o que está fazendo.

Quando ao lazy-exception, eu já repetí inúmeras vezes aqui no GUJ sobre isso, vocẽ pode dar uma pesquisada do meu histórico. É uma put* gambiarra você exportar suas entidades direto na web. Isso, na minha opinião falando em termos bem genéricos, é errado, é erro de desenho do projeto. Como que você simplesmente sai por aí largando todas suas classes persistences para a camada web sem dó nem piedade? Aí na web por alguma razão é feito um User.getRoles().clear() e o Spring/Hibernate exclui todas as roles do banco? Isso é certo? Ou então expor para a camada web a senha do usuário via Usuario.getPassword?

Se você tem esse pensamento, creio que você precisa ler realmente para que serve o DTO. É para transformação, e não para contornar o lazy-load. DTO existe muito antes dos tais “problemas” de lazy-load.

Estudar um pouco a especificação para entender os comportamentos é sempre bom. Assim evita que você tenha más interpretações de uma tecnologia.

[quote=garcia-jj]…Se você tem esse pensamento, creio que você precisa ler realmente para que serve o DTO. É para transformação, e não para contornar o lazy-load. DTO existe muito antes dos tais “problemas” de lazy-load.

Estudar um pouco a especificação para entender os comportamentos é sempre bom. Assim evita que você tenha más interpretações de uma tecnologia.[/quote]Exatamente,
Gracia, tenho plena consciência de para q q serve Pattern ‘DTO’: quando precisamos transferir Dados entre Tiers diferentes, não precisamos colocar na Chamada Remota [color=red]todos[/color] os Atributos de 1 Objeto Entidade: somente os q [color=darkred]realmente[/color] forem necessários (p/ exibição, etc.). Ou então, em vez de fazer um grande número de chamadas, contendo pouca informação: poderiamos agrupar (de forma razável). => Enfim, são técnicas de tunning (melhorar performance) em sistemas distribuidos, usando EJB. (Q, diga-se de passagem, muitos por aí nos fóruns da vida falam q essas tecnicas/padrões são 1 “marretada” para melhorar performance inserida no catálogo da Sun J2EE Core-Patterns.)
Obs.: p/ ser sincero, nunca pessei q vc fosse advocar p/ o EJB com tanta gana… Eu procuro divulgar o VRaptor, pq tudo q é nosso (do Brasil) a gente tem q defender, com todo o orgulho! 8) :thumbup:
Ok, muito bem! Vc falou “EJB não é apenas para aplicações distribuídas”. => então vamos ilustrar o seguinte Cenário:
:arrow: 1 Sistema para 1 Organização pequena (mas, q pode crescer) e tem q estar disponível na Internet;
:arrow: É decidido q vai rodar em somente 1 JVM;
:arrow: a Persistência deve ser gerenciada p/ Container.
:arrow: Framework Web + simples e produtivo o possível e q seja CoC (opção óbvia: VRaptor3);
:arrow: abordagem adotada: DDD (layered archteture);
É o suficiente! Levando em conta este Cenário, só p/ resolver o ‘LazyLoadExcecption’, ou o kamarada é obrigado a usar DTO, ou vai lá e (insipidamente) muda os atributos LazyLoad p/ Eager. :hunf:

[quote=garcia-jj]…
Quando ao lazy-exception, eu já repetí inúmeras vezes aqui no GUJ sobre isso, vocẽ pode dar uma pesquisada do meu histórico. É uma put* gambiarra você exportar suas entidades direto na web. Isso, na minha opinião falando em termos bem genéricos, é errado, é erro de desenho do projeto. Como que você simplesmente sai por aí largando todas suas classes persistences para a camada web sem dó nem piedade?[/quote]Deixa ver se eu entendi bem: então vc é contra usarmos POJOs (das Entidades de Negócio) do Model na cam. FrontController??! (Se sim, vc foi, no mínimo, polêmico! :shock: )
Eu entendi errado; foi isso q vc quis dizer??! :?: :roll:

[quote=garcia-jj] Aí na web por alguma razão é feito um User.getRoles().clear() e o Spring/Hibernate exclui todas as roles do banco? Isso é certo? Ou então expor para a camada web a senha do usuário via Usuario.getPassword?
…[/quote]Sobre ‘Usuario.getPassword’: IHMO o erro aki foi de Modelagem. Digo, faz realmente sentido expor um atributo tão crítico (informação ‘Senha’) desta forma??! E este é o maior equívoco: pensar q usando 1 acessor como 1 getter para acessar um atributo, eu estou deixando de violar o princípio Encapsulamento. Para ser mais exato, estamos então violando o principio ‘Esconder a Informação’ (Information Hidding). Assim, se a gente pensar melhor: não importa “em qual camada” - foi 1 erro de modelagem! Sacou??!
Ah, Garcia, muito interessante este outro ponto q vc levantou: hein, muito safadinho este Desenvolvedor UI q chama 1 ‘User.getRoles().clear()’. (Q sem-vergonha, hein?!! rsrsrsrs) Mas, brincadeiras a parte, acho q isso são coisas q nem os caras q projetaram a API da Linguagem/Plataforma Java e nem os q projetaram as APIs de Persistência poderiam imaginar: isto q vc falou é totalmente factível e acaba nos levando a 1 reflexão: como evitar isso, de quem é a falha??! (ficou 1 vácuo na verdade, não é?) E quer saber o pior? Isto não é nada obvio/trivial…

***Editado: galera, esqueci de mencionar, como orientado p/ Paulo Silveira (num blog da Caelum), para não sairmos criando getters e setters a torto a a direita “feito malukos”; só não tenho o link agora! :?

[quote=derlon][quote=garcia-jj]…
Quando ao lazy-exception, eu já repetí inúmeras vezes aqui no GUJ sobre isso, vocẽ pode dar uma pesquisada do meu histórico. É uma put* gambiarra você exportar suas entidades direto na web. Isso, na minha opinião falando em termos bem genéricos, é errado, é erro de desenho do projeto. Como que você simplesmente sai por aí largando todas suas classes persistences para a camada web sem dó nem piedade?[/quote]Deixa ver se eu entendi bem: então vc é contra usarmos POJOs (das Entidades de Negócio) do Model na cam. FrontController??! (Se sim, vc foi, no mínimo, polêmico! :shock: )
Eu entendi errado; foi isso q vc quis dizer??! :?: :roll:[/quote]

Não, você entendeu errado. POJO é uma classe apenas com getters e setters, e um DTO não deixa de ser um POJO. Errado é você largar as classes persistentes assim na web.

A entidade deve ficar dentro da sua camada de negócio, e não deve ir para a web. Quem vai para web é seu DTO, que não é uma simples classe qualquer, ela é uma classe que deve ter os objetos e atributos que você precisa para tal tela. (falando a grosso modo sem entrar em detalhes).

Derlon, leia esse meu post aqui e aí sim você vai entender meu ponto de vista. http://guj.com.br/posts/list/15/204519.java#1039241

Obvio que isso é um assunto que tem muito o que explorar, porém o espaço do texto no fórum é “pequeno” para isso, hehe.

Abraços

[quote=garcia-jj]…Vocẽ está confundindo as coisas. Service locator para buscar seus session beans, e não o persistence context e afins. Não há como injetar session beans em classes que não sejam controladas pelo container. No caso em servlets e backing beans você consegue injetar stateless-session-beans sem problemas.
…[/quote]Peraê, Peraê, Peraê…
Vamos esclarecer umas coisas aki, senão vai virar bagunça! :hunf:
(Ora, meu! O pessoal aki do GUJ gosta muito de dar “tapa na muleira”, desse jeito, eu acho q vô ter q mudar p/ JavaFree mesmo! :shock: )
Na verdade, eu nem mencionei nada sobre “session beans”, mas tudo bem!
Bem, para reposicionar todos, vou expor a micro-arquitetura q tenho em mente:
:arrow: 1 EntityManager injetado com @PersistenceContext no Repository (poder ser na DAO, para quem não é fã do DDD);
:arrow: Objetos do Model mapeados via JPA;
:arrow: Lógica de Negócio exposta via: ServiceFacade;
:arrow: (Web)FrontController usando a ServiceFacade via IoC.
(Com isto, espero agora evitar mal-entendidos.)

[quote=derlon][quote=garcia-jj]…Vocẽ está confundindo as coisas. Service locator para buscar seus session beans, e não o persistence context e afins. Não há como injetar session beans em classes que não sejam controladas pelo container. No caso em servlets e backing beans você consegue injetar stateless-session-beans sem problemas.
…[/quote]Peraê, Peraê, Peraê…
Vamos esclarecer umas coisas aki, senão vai virar bagunça! :hunf:
(Ora, meu! O pessoal aki do GUJ gosta muito de dar “tapa na muleira”, desse jeito, eu acho q vô ter q mudar p/ JavaFree mesmo! :shock: )
Na verdade, eu nem mencionei nada sobre “session beans”, mas tudo bem!
Bem, para reposicionar todos, vou expor a micro-arquitetura q tenho em mente:
:arrow: 1 EntityManager injetado com @PersistenceContext no Repository (poder ser na DAO, para quem não é fã do DDD);
:arrow: Objetos do Model mapeados via JPA;
:arrow: Lógica de Negócio exposta via: ServiceFacade;
:arrow: (Web)FrontController usando a ServiceFacade via IoC.
(Com isto, espero agora evitar mal-entendidos.)[/quote]

Mas que nervosismo, derlon. Se você bebe a cerveja é por minha conta. Senão pago uma pizza com guaraná :smiley: Posso ter entendido errado, acontece. :oops:

Opa, Garcia!! Muitíssimo bem-vindo o seu convite! :thumbup: (q Pena vc não estar aki no DF :()
Fico contente em vc esta começando a compreender o meu ponto de vista…

Opa mal por ter ficado ausente, não sei por que parei de receber email daqui vou verificar minhas config aqui do forum.

Só pra constar como fico meu caso:

Resolvi meu problema com o get/set gambiarrento mesmo, mas foi uma solução provisória pois pretendo criar os DTO para não expor meus model para fora da camada EJB que ao meu ver parece ser a alternativa melhor e mais segura mesmo.

Obrigado a todos que colaboraram com post ajudou a me esclarecer bastante ainda mais pra mim que estou iniciando com EJB.

[quote=derlon]Opa, Garcia!! Muitíssimo bem-vindo o seu convite! :thumbup: (q Pena vc não estar aki no DF :()
Fico contente em vc esta começando a compreender o meu ponto de vista…[/quote]

Derlon, compreender seu ponto de vista eu entendi desde o início, porém eu não concordava (e nem concordo ainda); assim como naquela discução de validações no client/server. Mas por um lado é bom termos lados opostos e expor nossas idéias na mesa, porém evitando cair em brigas.

:thumbup:

@garcia-jj, no q vc disse: “Lazy remoto é uma put* gambiarra, e até existe um projeto para isso, o H3T. Mas no próprio site do projeto diz que lazy remoto viola a especificação e que não é aconselhado mesmo.”=> nisso (“artimanhas como o remote-lazy-load via HT3” :hunf: ser 1 gambiarra “na alta”), concordo plenamente contigo!

[quote=garcia-jj][quote=derlon]Deixa ver se eu entendi bem: então vc é contra usarmos POJOs (das Entidades de Negócio) do Model na cam. FrontController??!..[/quote]Não, você entendeu errado. POJO é uma classe apenas com getters e setters, e um DTO não deixa de ser um POJO.[/quote]hei, de acordo c/ a sua explicação, o DTO é um… (como 1 galera aê diria) …um “Bean” =P

Garcia, na atual conjuntura, não tenho como discordar de vc q neste cenário (em q não seja possível se livrar do EJB) a única opção/solução realmente é usar o Padrão DTO. @jingle, apenas um parêntese: o ‘T’ de DTO e TO significa Transfer=>Transferencia de Dados. Porem, neste Cenário o Objeto não passa de 1 tier (camada física) para outra, o idéal não seria vc chama de DO (isso mesmo: Objeto de Dados); concorda, Garcia??! (Mas, já sinto 1 grande alívio só de vc não chamá-lo de VO! :shock: )
Mas, tb não posso deixar de mencionar:
"Não me lembro de nenhum padrão J2EE que não tenha sentido apenas para suprir uma deficiência da plataforma, mas o DAO, IMHO, é mais que isso, age na impedância (cadê o link apra aquele outro tópico?). É ideal? Claro que não, mas funciona (Como DTOs, que até hoje eu busco algo que possa eliminar)."
Quem falou isto não foi eu, não; foi o Phillip “Shoes” Calçado! A ref. em: http://www.guj.com.br/posts/list/20668.java (Ah, eu só substituiria o termo “plataforma” pelo termo “API do EJB”.)
A conclusão q tiramos disso é q o DTO (e uma grande parte dos outros Padrões do catálogo J2EE Core-Patterns) só foi “inventada” para melhoria de performance (para “suprir uma deficiência da” “API do EJB”).

[quote=garcia-jj] Errado é você largar as classes persistentes assim na web.
.
A entidade deve ficar dentro da sua camada de negócio, e não deve ir para a web. Quem vai para web é seu DTO, que não é uma simples classe qualquer, ela é uma classe que deve ter os objetos e atributos que você precisa para tal tela. (falando a grosso modo sem entrar em detalhes).

Derlon, leia esse meu post aqui e aí sim você vai entender meu ponto de vista. http://guj.com.br/posts/list/15/204519.java#1039241

Obvio que isso é um assunto que tem muito o que explorar, porém o espaço do texto no fórum é “pequeno” para isso, hehe.

Abraços[/quote]Sinto muito, mas nisto eu vou ter q discordar de vc, Garcia. Olha, para vc/v6 entenderem o meu ponto, é sugerida a (pelo menos 1 rápida) leitura do seguinte artigo: http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html?page=1
Claro q não podemos tomar como lei universal (e irrevogável) tudo o q os autores falam: devemos ter senso crítico.
Mas, acho q podemos tirar boas lições (e dicas). Garcia, em outro post vc levantou interessantes aspectos: 1 deles é o “do Desenvolvedor UI q chama 1 ‘User.getRoles().clear()’ e depois poderia salvar o User”. Sei q já estou começando a ir off-topic, mas não tem jeito:
[off-topic - ***]
para o atributo ‘roles’ (para não dizer bobo) seria estúpido disponibilizar um método ‘setRoles()’ => se o q realmente faz sentido é adicionar (ou remover) papeis de um Usuário. Isto é uma falha de Modelagem: não fizemos o ‘Hidding of Information’! E quanto ao ‘User.getRoles()’, a falha é maior ainda, pois acabamos expondo a estrutura Interna (q poderia ser um array (de Role’s), um List, um Set, ou até mesmo um (Hash)Map) da Composição de Papeis de um Usuário; quando o correto seria (além de forncecer o métodos adicionar e remover) fornecer um método q retornasse, não a própria Referência do atributo (interno) Roles, mas uma cópia (um tipo de Clone) desta composição. Conseguem me compreender?!
Creio q devemos fazer um reflexão sobre o design da Modelagem e Projeto q costumamos fazer no Desenvolvimento de nossas Aplicações.
Garcia, q tal abrimos um discussão s/ a questão do LazyInicializationException / Expor Objetos de DomainModel fora do Business-Core: poderiamos fazer isso usando o Pattern Memento, ou Prototype, ou ainda uma implementação (+) simples de um deles??! Ou quem sabe simplesmente usar o .clone() da API do Java, o q acha??!
[/off-topic - ***]
Ah e sobre: [quote=garcia-jj]Mas por um lado é bom termos lados opostos e expor nossas idéias na mesa, porém evitando cair em brigas.[/quote]Concordo plenamente contigo, pois a discussão leva ao crescimento! :thumbup: E sobre “brigas”: no way! :shock:

Derlon, há dois bons artigos que podem acrescentar na discução sobre lazy-load, dtos e afins.

http://community.jboss.org/wiki/HibernateinaLayeredArchitecture
http://community.jboss.org/wiki/RemoteLazyLoading

:thumbup: Muito espírito crítico para saber avaliar cada um dos patterns. Muitos são inúteis em alguns casos, mas úteis noutro. O pior que conheci um projeto em EJB 2.1 que usava TODOS os patterns. E sabe que ficou bem elegante? No caso desse projeto era mesmo necessário usar aquilo tudo, mas hoje em dia com EJB3 eu não faria assim.

[quote]Mas, acho q podemos tirar boas lições (e dicas). Garcia, em outro post vc levantou interessantes aspectos: 1 deles é o “do Desenvolvedor UI q chama 1 ‘User.getRoles().clear()’ e depois poderia salvar o User”. Sei q já estou começando a ir off-topic, mas não tem jeito:
[off-topic - ***]
para o atributo ‘roles’ (para não dizer bobo) seria estúpido disponibilizar um método ‘setRoles()’ => se o q realmente faz sentido é adicionar (ou remover) papeis de um Usuário. Isto é uma falha de Modelagem: não fizemos o ‘Hidding of Information’! E quanto ao ‘User.getRoles()’, a falha é maior ainda, pois acabamos expondo a estrutura Interna (q poderia ser um array (de Role’s), um List, um Set, ou até mesmo um (Hash)Map) da Composição de Papeis de um Usuário; quando o correto seria (além de forncecer o métodos adicionar e remover) fornecer um método q retornasse, não a própria Referência do atributo (interno) Roles, mas uma cópia (um tipo de Clone) desta composição. Conseguem me compreender?!
[/quote]

Aí e que está meu ponto. Em muitos códigos que vemos aqui no GUJ o pessoal carrega uma entidade, User por exemplo, e simplesmente retorna isso ao controller. Ou seja, qualquer coisa que for feita no meio do caminho altera o estado do objeto, e como há um open-session-in-view o objeto é persistido normalmente.

[quote=garcia-jj]Derlon, há dois bons artigos que podem acrescentar na discução sobre lazy-load, dtos e afins.
http://community.jboss.org/wiki/HibernateinaLayeredArchitecture
http://community.jboss.org/wiki/RemoteLazyLoading

[quote] A conclusão q tiramos disso é q o DTO (e uma grande parte dos outros Padrões do catálogo J2EE Core-Patterns) só foi “inventada” para melhoria de performance (para “suprir uma deficiência da” “API do EJB”).[/quote] :thumbup: Muito espírito crítico para saber avaliar cada um dos patterns. Muitos são inúteis em alguns casos, mas úteis noutro. O pior que conheci um projeto em EJB 2.1 que usava TODOS os patterns. E sabe que ficou bem elegante? No caso desse projeto era mesmo necessário usar aquilo tudo, mas hoje em dia com EJB3 eu não faria assim.
[/quote]