EJB3 (JPA) e DTO´s

Olá,
Num sistema não-distribuído, usando POJOS do JPA, é necessário usar DTO? Gostaria de pedir que evitemos divagações conceituais sobre DTO.

Sávio Barros

[quote=saviobarr]Olá,
Num sistema não-distribuído, usando POJOS do JPA, é necessário usar DTO? Gostaria de pedir que evitemos divagações conceituais sobre DTO.

Sávio Barros[/quote]

Não, na verdade o DTO só faria sentido realmente se fosse utilizado para reduzir seu tráfego de rede e número de chamadas remotas utilizando algo ruim como EJB 2.1 hehe .

Se seu sistema não vai ser distribuído, não faz sentido ter DTO na sua aplicaçã e caso esteja usando EJB3 por algum motivo também, já que não vai ter nada distribuído hehehe , DTO é um Anti-Pattern, já que o Entity pode representar seu modelo e basta você implementar Serializable e detach para envio :slight_smile:

Falae mano, tudo certo?

O DTO na real foi criado para suprir o problema do EJB 2 quando se tratava de Entity Beans. Cada chamada de método de um Entity Bean no EJB2 (um getXXX por exemplo) resultava numa chamada remota. Por isso que o principal problema que o DTO resolve é o tráfego na rede, você faz somente uma chamada que vai retornar os dados necessários em vez de fazer várias chamadas para pegar a mesma quantidade de dados

Agora, se você por exemplo, utiliza JPA com o EntityManager sem ser extended, o Uso de DTO pode ser necessário. Por exemplo, imagina que você quer iterar pelos filhos de uma classe específica por lazy-loading. Quando você utiliza o EntityManager não-extend, ele precisa estar dentro de um escopo transacional para funcionar, senão uma exception vai ser jogada.

[quote=Leozin]Falae mano, tudo certo?

O DTO na real foi criado para suprir o problema do EJB 2 quando se tratava de Entity Beans. Cada chamada de método de um Entity Bean no EJB2 (um getXXX por exemplo) resultava numa chamada remota. Por isso que o principal problema que o DTO resolve é o tráfego na rede, você faz somente uma chamada que vai retornar os dados necessários em vez de fazer várias chamadas para pegar a mesma quantidade de dados

Agora, se você por exemplo, utiliza JPA com o EntityManager sem ser extended, o Uso de DTO pode ser necessário. Por exemplo, imagina que você quer iterar pelos filhos de uma classe específica por lazy-loading. Quando você utiliza o EntityManager não-extend, ele precisa estar dentro de um escopo transacional para funcionar, senão uma exception vai ser jogada.

[/quote]
É, eu li isso no livro no livro do Panda (EJB3 in Action). Foi uma gambi pra suprir uma deficiencia do EJB 2.X. É que aqui no projeto nêgo queria por que queria usar isso aleatoriamente. Resolvi pegar mais opiniões pra formar minha opinião.

Abração

Sávio

Kenobi disse tudo. Criar um DTO para cada Entity EJB3 nao faz sentido. O Entity bean já age como um DTO!

Existem RAROS casos em que voce deve fazer um DTO para Entity Bean do EJB3: imagine que voce tem 3 entidades relacionadas, e quer buscar uma informacao que junta partes das 3. Em vez de voce retornar TUDO, voce cria uma classe, um POJO qualquer, que contem aqueles dados, e popula atraves da JPA QL e manda os objetos pro cliente. Mas essa classe nem precisa ter sufixo DTO, acho ate mais elegante: pro cliente nao fara diferenca se aquilo é um @Entity, um @Embeddable ou um DTO. Tudo é POJO.

Hum, essa solução é campeã, Paulo!

Valeu, vou adotar…

[quote=Paulo Silveira][quote=Kenobi]

DTO é um Anti-Pattern, já que o Entity pode representar seu modelo e basta você implementar Serializable e detach para envio :slight_smile:

[/quote]

Kenobi disse tudo. Criar um DTO para cada Entity EJB3 nao faz sentido. O Entity bean já age como um DTO!

Existem RAROS casos em que voce deve fazer um DTO para Entity Bean do EJB3: imagine que voce tem 3 entidades relacionadas, e quer buscar uma informacao que junta partes das 3. Em vez de voce retornar TUDO, voce cria uma classe, um POJO qualquer, que contem aqueles dados, e popula atraves da JPA QL e manda os objetos pro cliente. Mas essa classe nem precisa ter sufixo DTO, acho ate mais elegante: pro cliente nao fara diferenca se aquilo é um @Entity, um @Embeddable ou um DTO. Tudo é POJO. [/quote]

Sim, usando o DTO junto no Select new

nesses casos são perfeitamente aplicáveis o uso de DTOs :stuck_out_tongue:

[quote=Leozin]
Sim, usando o DTO junto no Select new

nesses casos são perfeitamente aplicáveis o uso de DTOs :P[/quote]

Exato!!! Select NEW é o que ha!

EntityManager extended implica em um stateful session bean, certo? Imagine um caso onde se está utilizando EJBs stateless para implementar uma camada de serviço e imagine uma classe com um monte de associações n-árias. Imagine que em um dado contexto, alguns objetos desta classe serão obtidos do EJB e algumas destas associações serão necessárias para mostrar ao usuário (uma consulta, por exemplo) e outras não. Em outro contexto, outras destas coleções associadas serão necessárias. Como o objeto mestre estará detached, (1) teria que ser utilizado eager fetching para tudo (o que geraria consultas com um monte de joins desnecessários), ou (2) teriam que existir vários métodos para obter objetos da mesma classe dependendo do contexto, já com as coleções necessárias para cada situação. Ambas as situações são indesejáveis, uma por ineficiência, outra por improdutividade e poluição do código. Como não é caso de workflow, não acho que stateful seria uma boa solução.

Já vi por aí algumas soluções usando aspectos, porém a minha dúvida é: há alguma solução para o problema do lazy loading detached que seja limpa e simples? Como as pessoas têm feito para lidar com isto?

Neste caso use o Seam que ele faz o extend da Persistence Context mesmo para os Stateless :stuck_out_tongue:

É, eu já havia cogitado o Seam, acho que vai ser ele mesmo! Obrigado pela ajuda!