EJB 3.0 com ou sem Data Transfer Object

Estava discutindo com um colega sobre uma melhor abordagem para o projeto que estou trabalhando com EJB 3.0.

Ele defende a utilizacao dos proprios Entity Beans, ja que sao POJOs, para o envio de dados para a camada de apresentacao. Diminuindo o overhead de se ter um DTO na comunicacao entre camadas.

Eu defendi uma abordagem utilizando DTOs, partindo do principio de estabelecer uma interface de comunicacao entre camadas, de forma a criar abstracao entre as mesma e que alteracoes na camada de negocio e/ou persistencia nao impactem ou tenho um baixo impacto na apresentacao.

Qual a opniao de vcs?

Só uma pergunta, os entitys são serializable?

Sim,

mas a questao aqui levantada eh arquitetural e nao tecnica

[quote=diego.baldin]Estava discutindo com um colega sobre uma melhor abordagem para o projeto que estou trabalhando com EJB 3.0.

Ele defende a utilizacao dos proprios Entity Beans, ja que sao POJOs, para o envio de dados para a camada de apresentacao. Diminuindo o overhead de se ter um DTO na comunicacao entre camadas.

Eu defendi uma abordagem utilizando DTOs, partindo do principio de estabelecer uma interface de comunicacao entre camadas, de forma a criar abstracao entre as mesma e que alteracoes na camada de negocio e/ou persistencia nao impactem ou tenho um baixo impacto na apresentacao.

Qual a opniao de vcs?

[/quote]

Não vejo qualquer sentido em usar DTOs com EJB 3.0

nao perguntei sobre tecnica, eh pq se nao fossem serializable nao serviria, pra trafegar em rede nao sendo serializable eh loucura…

Concordo! E acrescento que, além de não ver sentido, penso que essa abordagem tem uma série de desvantagens.

O tutorial sobre Java EE 5 da SUN ainda faz uso de DTO’s (vejam aqui: http://java.sun.com/javaee/5/docs/tutorial/doc/DukesBank2.html#wp79750), e eu acho isso bem estranho.

E por misturar entity beans com DTO’s, tiveram que colocar toda a lógica de validação nos session beans (façades). Resultado: código confuso, cheio de duplicações, chato, bobo e feio.

Eu prefiro esquecer DTO’s, usar apenas entities e colocar métodos de validação referentes ao domíno que abstrai no próprio entity bean, não no façade.

Ta mais a questao de vc estar enviando um entity bean , que eh um objeto de persistencia, para a camada de apresentacao, nao cria um acoplamento entre as camadas?

Embase melhor a resposta sobre nao haver nescessidade nenhuma de DTO com EJB3.

e digamos q eu tenha um sistema que acessa fontes de dados diferentes, como exemplo Banco de DAdos e WebServices,
Quero uma camada de negocio transparente para quem utiliza-la.
Digamos que no acesso a Banco eu utilize Entities Beans 3.0 para mapeamento O/R, voce continuaria usando eles para transporte de dados atraves das camadas.

Como definiria uma interface de comunicacao transparente para os clientes desta Bussiness Tier?

Caso a tua aplicação não seja disstribuída/você não precise trafegar teus objetos pode diversos pontos diferentes da rede, então não há sentido para o uso de Transfer Objects. Pois o próprio padrão do CJP foi criado com o intuito de diminuir o overhead da sua rede nas chamadas remotas.
Eu particularmente não vejo problemas em retornar meus objetos de domínio para a camada de apresentação na maioria dos casos.

[quote=CJP]
"…To reduce the number of remote calls and to avoid the associated overhead, …"[/quote]

[quote=diego.baldin]e digamos q eu tenha um sistema que acessa fontes de dados diferentes, como exemplo Banco de DAdos e WebServices,
Quero uma camada de negocio transparente para quem utiliza-la.
Digamos que no acesso a Banco eu utilize Entities Beans 3.0 para mapeamento O/R, voce continuaria usando eles para transporte de dados atraves das camadas.

Como definiria uma interface de comunicacao transparente para os clientes desta Bussiness Tier?[/quote]

Aí dependeria primeiro se eu conheço quem são meus clientes, caso sim, abstraio a forma de retorno, caso não, trataria-as de forma diferente.

Ok! Vou dizer o que me incomoda! DTO é uma padrão gambiarra para passar dados por camadas remotas - do banco de dados até o cliente remoto e vice-versa - algo que CMP’s não conseguiam fazer porque estavam amarrados ao servidor de aplicativos. Os entity beans (JPA) resolveram isso. Ou seja, DTO’s para mim é inútil. (Eu disse para mim. Alguém ainda pode achar isso útil, vai saber.)

[quote]
Digamos que no acesso a Banco eu utilize Entities Beans 3.0 para mapeamento O/R, voce continuaria usando eles para transporte de dados atraves das camadas.[/quote]
Qual o problema nisso? São objetos de domínio (i.e. tem dados sobre o negócio). O mesmo que o cliente vê na tela será cadastrado no banco de dados.

Com DTO’s vc tem uma tremenda duplicação de código, pois terá que passar os dados do objeto de domínio para um DTO e vice-versa. Além do que, com entity bean eu tenho verdadeiros objetos de negócio, com atributos e comportamento. Dessa forma, métodos de negócio pertinentes ao objeto ficam dentro dele, não fora dele.

Ex: se eu tenho um Cliente, o próprio objeto pode verificar se todos os dados necessários foram preenchidos corretamente, ao invés de um session façade.

Resumidamente, algo assim:
Cliente -> Service -> DAO
DAO -> Service ->Cliente

Eu não vejo entity beans como objetos de persistência, mas sim de negócios.
Tua vez! :smiley:
Por favor, me explique onde você vê acoplamento entre camadas ao utilizar entity beans.

o Entity esta para a persistencia assim como o Session esta para o negocio.

Qdo vc cria um Entity Bean 3.0 eh algo semelhante a isso?

@Entity
@Table(name = “USUARIO”, schema = “GUJ”, uniqueConstraints = {})
public class Usuario implements java.io.Serializable {

// Fields    	

private String dscLogin;

private String dscSenha;

// Property accessors
@Id
@Column(name = "DSC_LOGIN", unique = true, nullable = false,      insertable = true, updatable = true, length = 10)
public String getDscLogin() {
	return this.dscLogin;
}

public void setDscLogin(String dscLogin) {
	this.dscLogin = dscLogin;
}

@Column(name = "DSC_SENHA", unique = false, nullable = false, insertable = true, updatable = true)
public String getDscSenha() {
	return this.dscSenha;
}

@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "scaUsuario")
public Set<ScaUsuarioPerfil> getScaUsuarioPerfils() {
	return this.scaUsuarioPerfils;
}

public void setScaUsuarioPerfils(Set<ScaUsuarioPerfil> scaUsuarioPerfils) {
	this.scaUsuarioPerfils = scaUsuarioPerfils;
}

Isso para mim eh um componente de persistencia projetado para Mapeamento O/R.

A questao do acoplamento que citei eh justamente por o Concern de um Entity Bean eh refletir no mundo Orientado a Objetos Dados do Mundo Relacional. Na minha visao esta eh a funca do Entity Bean.

A questao de vc estar enviando esse mesmo entity para a camada de apresentacao para digamos ser utilizado para mostrar dados em uma pagina JSP, vc esta acoplando o jsp ao entity Bean.

Ok o entity bean eh um pojo, portanto vc pode retirar os annotations, e pronto, deixou de ser um entity bean e passou a ser um VO.

O DTO realmente concordo que cria um overhead grande e muitas vezes desnecessario. Porem ele prove este tipo de abstracao.

Digamos q eu precise ou queira mudar a minha camada de persistencia.

CASO 1: com uma camada de DTO essa mudanca eh transparente para a apresentacao.

CASO2: Com entities beans vc pode retirar todos os anotations e ele passara a ser um POJO e tera justamente a funcao de um DTO. e vc tera o overhead provido pelo DTO.

CASO3: pode mudar todos os POJOS trafegados entre as camadas.

eh…realmente com ejb 3.0 acho q DTO nao sao nescessarios.

Você levantou uma questão interessante, mas até onde eu sei DTO’s nem foram feitos para resolver esse tipo de problema. Foram feitos para pura e simplesmente carregar dados com uma granulação mais grossa de uma camada remota a outra para evitar o overhead que ocorreria graças a múltiplas chamadas remotas.

E com a minha (pouca) experiência, eu ainda não consegui fazer uma abstração tão poderosa quanta essa que você pretende. Se eu chegar a fazer uma alteração tão profunda no domínio do sistema, provavelmente eu teria que refatorar todo o sistema. Mas isso num caso extremo certo? Tipo, eu começo a fazer um sistema de automação comercial e termino com uma loja virtual! :lol:

[quote=diego.baldin]o Entity esta para a persistencia assim como o Session esta para o negocio.
[/quote]

Isso era verdade com o modelo anmico de EJB2.1, não com Hibernate ou JPA.

Isso é um POJO com metadados para persistencia.

Esta 8era* a função de um Entity Bean 2.x. JPA pressupõe um modelo rico com objetos de negócio, não dados de um lado e funções de oturo. Aliás, essa é a grande vantagem de JPA e hibernate.

Como os ‘entity beans’ de JPA são apenas POJOs e estes são objetos de negócio não há acoplamento entre persistência e apresentação :wink:

Apresentação depende apenas de negócios, como normalmente aplicação e apresentação estão juntas isso não é um problema.

Nesse caso ele deve virar um objeto de negócios, não apenas um container de dados.

O problema aqui, creio, é que você está utilizando JPA na camada de persistncia e não na de negócios, o que não é para que ela se propõe. O objetivo de JPA é dar aos objetos de negócio mapeamento OR.

Da forma que você coloca não há um domain model, sequer uma camada de negócios e este é o problema.

[quote=seufagner]
Não interessa pra que foram feitos. A questão é “resolve seu problema?” Pra que encher a sacola de patterns ou frases-prontas-de-efeito se não resolve teu problema? [/quote]
Eu penso da mesma forma. Na verdade quem está falando em patterns é você, com o DTO. Eu não citei nenhum. Muito pelo contrário, disse que com entity beans não precisaria de mais um pattern - o DTO.

[quote=seufagner]
Pra isso que existem testes.
Se teu negócio muda, tu vai refatorar e pronto. sempre rodando teus testes… Ah, e acredite, ele muda pra…[/quote]
Sim, claro. E esse é mais um motivo para eu não usar DTO’s. Está muito fácil testar entity beans, já que rodam fora do container.

[quote]Esse é o óbvio que alertei
" Ah, mas aí vem aquele papo blábláblá "[/quote]
Esse é o tipo de coisa que escrevem quando começam a faltar argumentos técnicos para se defender uma idéia. E me mostra onde está a frase pronta (de efeito eu sei que foi).

[EDITADO]
E seja feliz com os seus DTO’s! :stuck_out_tongue:
[/EDITADO]

topico muito interessante,

alguem conhece bons livros que trata desses itens: dto, entity, session…?

mas JPA = Java Persistence API, certo…se ela se destina ao negocio pq o nome.

Na verdade as camadas estao definidas da forma classica: Session Beans para negocio, Entity Beans para Persistencia. Acesso a Session Atraves de Bussines Delegate com Service Locator.

Mas eu nao concordo na parte que vc diz q JPA foi criado para dar objetos de negocio Mapeamento OR e sim numa forma de acabar com toda a complexidade que existia no EJB 2.X

No EJB 2.x muita complexidade era diratamente imposta ao desenvolvedor, com o EJB 3 a ideia eh transparecer um modelo simples de desenvolvimento para quem utiliza e deixar a complexidade desnessaria para o container.

Porque ela provê persistêrncia para POJOs, como eu disse no post anterior.

Clássica?!? Clássica de quem?!? De EJB 2.x, talvez, mas não de nenhuma definição ou trabalho sobre camadas que eu conheça (isso incluir Fowler, Buschman, Evans, Page-Jones e outros).

Camadas dizem como objetos são agrupados e nao como são estruturados. Pode, por favor, achar uma definição válida que diga isso para EJB 3.0 ou isso é a sua opinião? Se for a sua opinião pode, por favor, embasá-la?

Service Locators, aliás, são antítese ao modelo baseado em IOC proposto pelo Java EE 5.0 (‘inspirados’ em Spring e Pico Container).

Da especificação:

Se você vai criar um domain model você não vai separar classes em lógica e dados.

Não só, isso, se você conhece as vantagens de um modelo baseado em POJOs vai ver que JPA e Java EE 5.0 em geral são apenas uma tentativa de traz-los para o padrão oficial, não apenas como opções alternativas de modelos baseados em Spring e Hibernate.

[quote=diego.baldin]
No EJB 2.x muita complexidade era diratamente imposta ao desenvolvedor, com o EJB 3 a ideia eh transparecer um modelo simples de desenvolvimento para quem utiliza e deixar a complexidade desnessaria para o container. [/quote]

Não só isso bem como eliminar o modelo de programação procedural introduzido com especificações anteriores.

Eu também utilizaria VOs/DTOs…

Nestes você poderia ter atributos da classe “interessantes” apenas à VIEW, que satisfazem à mesma, não interferindo no DOMAIN do teu sistema…

[quote=Taz][quote=diego.baldin]Estava discutindo com um colega sobre uma melhor abordagem para o projeto que estou trabalhando com EJB 3.0.

Ele defende a utilizacao dos proprios Entity Beans, ja que sao POJOs, para o envio de dados para a camada de apresentacao. Diminuindo o overhead de se ter um DTO na comunicacao entre camadas.

Eu defendi uma abordagem utilizando DTOs, partindo do principio de estabelecer uma interface de comunicacao entre camadas, de forma a criar abstracao entre as mesma e que alteracoes na camada de negocio e/ou persistencia nao impactem ou tenho um baixo impacto na apresentacao.

Qual a opniao de vcs?

[/quote]

Não vejo qualquer sentido em usar DTOs com EJB 3.0[/quote]

Não é no próprio EJB ou na interação entre os beans, é no cliente. Ao receber dados dos Entitys e passar para a view através de um VO

diego.baldin, eu estou me questionando quanto a isso. Nem sempre o que tua view quer é o que tua classe de domínio provê…

Por exemplo:
Uma transação que envolve vários entitys e o produto desta interação deve te retornar valores diversos sobre seus relacionamentos. Você vai passar um Entity (POJO normal se detached) para a VIEW? E se você tiver que fazer alterações, por mais sensíveis que sejam, no teu domínio (evoluí-los, refatorar), como fica tua view ? Tenha em mente que modificando eles o impacto será refletido em todos os templates que utilizam os mesmos para apresentar dados.

Ah, mas aí vem aquele papo blábláblá de que VOs segundo Martin Fowler… Então como resolvo? Vou criar esta dependência mesmo?

Acho que não precisa ser tão purista. Não sei… Me critiquem porque penso nisso daí há um tempo…

[]s