| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/08/2009 14:54:10
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Oi pessoal
Estou escrevendo sobre persistência, e cai na polêmica parte de DAO, Mappers, EntityManager e patterns.
Essa é uma antiga discussão. Devo usar DAO se estou em um ambiente com EJB+JPA?
http://www.infoq.com/news/2007/09/jpa-dao
O Adam Bien té da opiniao que nao devemos mais usar o DAO, e acessar o EntityManager diretamente (em especial se só for um wrapper):
http://www.adam-bien.com/roller/abien/entry/jpa_ejb3_killed_the_dao
Obviamente isso pode gerar confusoes e muita gente fazendo os mesmos procedimento, processando as mesmas entidades de certa forma que uma query nao permitiu buscar, etc. Tanto que ele da um passo pra trás e diz que você pode sim ter um DAO:
http://www.adam-bien.com/roller/abien/entry/you_should_dao_if
Os posts do Vincent Partington (muito bem escritos) ganharam muita popularidade esse ano, e vão para o outro lado, apoiando o uso do DAO (assim como outros):
http://blog.xebia.com/2009/03/09/jpa-implementation-patterns-data-access-objects/
http://gleichmann.wordpress.com/2007/11/22/why-dao-wont-die/
(uma observação, o Vincent ainda aborda outros dois tópicos que eu concordo com ele: tomar cuidado com relacionamento bidirecional de entidades, e que o DTO não está morto, pode ser usado para ajustar granularidade (apenas quando necessário, claro)).
Curioso que essa discussão reaparece inúmeras vezes, e se você for ver, a galera do Spring tem uma opinião, a galera do Hibernate outra, do Glassfish outra, e assim por diante.
Sei que muitos tem preferências (eu também tenho) mas eu gostaria links e referências que deem base para a escolha. Qual é a sua preferência?
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/08/2009 15:43:10
|
Leonardo3001
GUJ Ranger
Membro desde: 04/07/2007 18:28:58
Mensagens: 975
Offline
|
Eu acredito que existam "forças" que levam ao incentivo ou à rejeição do DAO.
As que rejeitam o uso do DAO acontece quando:
Boa parte da funcionalidade do programa se resume a CRUD. Afinal, não há o que esconder, o negócio é o acesso ao banco.
A funcionalidade é chamada genericamente de "relatório".
As que incentivam o uso de DAO acontece quando:
o banco é legado e não reflete a maneira como se pensa o negócio.
a entidade persistida possui vários estados onde, em alguns deles, não se permite a inserção/alteração/remoção. O DAO pode impedir operações de maneira consistente.
o negócio é complexo, exigindo separar qualquer coisa que impeça uma visão em alto nível.
De qualquer maneira, o JPA sempre vazará a transação, o que significa que só ela é incapaz de encapsular o acesso aos dados. Também existe o movimento dos bancos pós-relacionais ou NoSQL, onde o JPA é simplesmente a abstração errada. Portanto, abandonar DAO (e usar os EntityManagers diretamente) pode não ser uma vantagem se considerarmos todas as ofertas de persistência.
This message was edited 1 time. Last update was at 02/08/2009 15:44:14
|
Leonardo Veríssimo
-------------------------------------------------
Objectzilla |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/08/2009 23:45:09
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Ola Leonardo
Acho que é bem por aí mesmo. Sua opinião está mais para o lado do Vincent (a minha também é para esse lado). Curioso a Sun não se posicionar nesses anos todos em relação a essas boas práticas, e ficarmos com o Core J2EE Patterns mais que outdated.
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 01:09:14
|
Alessandro Lazarotti
Virtual Machine Man
![[Avatar]](/images/avatar/2aaaddf27344ee54058548dc081c6541.jpg)
Membro desde: 21/01/2004 14:12:54
Mensagens: 719
Offline
|
Penso que depende do projeto e de como esta o resto de sua modelagem.
Quem vem do Java do período jurássico after ORM, lembra de:
- GenericFirebirdDAO implements GenericDAO
- CustomerOracleDAO implements CustomerDAO
- NotaFiscalMySQLDAO implements NotaFiscalDAO
- RapaduraPostgresDAO implements RapaduraDAO
... maravilha, conseguimos ter nosso projeto "multi-banco".
A idéia era abstrairmos o banco, ja que as instruções SQL sempre tinham suas particulariedades lock-in. A vantagem comercial é clara.
Com as ORMs, começamos a pensar diferente. Vou fazer a persistencia em JDO pra abstrair o banco, mas e se quiser mudar para o Apache OJB, KODO ou Prevayler? Vou fazer em Hibernate, mas e se quiser mudar para o iBatis? E por aí vai... então começaram a "era" dos:
- CustomerHibernateDAO implements CustomerDAO
... maravilha, temos nosso projeto a prova de mudança de tecnologia. Hmm, mas quantos deles realmente mudamos de tecnologia? Quantos projetos reescrevemos "toda" camada de persistencia de Hibernate para qualquer outra coisa? Pessoalmente, ja vi muito dinheiro com horas de desenvolvimento sendo jogadas fora para interfaces cuja implementação nunca passou de uma classe concreta/per interface.
Mas vamos misturar regras de negócio com códigos de banco? Pra isso temos outros padrões como ActiveRecord, Repository, QueryObjects etc. DataAcessObject quase sempre é implementação de DataMapper, e para isso os ORMs fazem bem o papel. Os outros padrões tem características diferentes e não são de fato DAOs.
Logo, hoje, se utilizo um desenvolvimento like DDD, uso Repository para fazer parte do codigo com uma implementação onde a API do ORM é exposta... aos moldes de Applying-Domain-Driven-Design-Patterns-Examples. Se o projeto não justifica um domain-driven, descarto repository (embora um possa existir sem o outro). Neste caso utilizo EntityManager com suas NamedQueries diretamente, sem medo de ser feliz, chutando pra longe aqueles DAOs onde tinha :
- dao.save() -> entityManager.persist()
- blaDao.buscarBlaMaiorQueFulano() -> entityManager.createNamedQuery(?bla.buscarBlaMaiorQueFulano?)
Quase sempre, não sinto falta neste caso dos DAOs. "Quase", pq quando se fala em testes unitários...hmm. Nisso tendo a granularidade em DAOs ou Repositories pode lhe ajudar mais do que atrapalhar.
Paulo, os BluePrints do JavaEE 5 da SUN mostram que "ModelFaçade" é a bola da vez para abstrair as chamadas a JavaPersistence API. DAOs estão fora da jogada:
https://blueprints.dev.java.net/bpcatalog/ee5/persistence/
This message was edited 1 time. Last update was at 03/08/2009 01:09:45
|
... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.org/
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 01:39:16
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Alessandro, mais um excelente post seu, obrigado!
Mas quando sua named query nao é suficiente para trazer o que você precisa, e você precisa de um pós processamento da sua lista de entidades (seja para sumarizar alguma infiormação, seja para uma operação em lote de "data logic"), onde você poe isso?
E de qualquer maneira esse ModelFacade esta bem próximo de um DAO, correto? (vale lembrar da Sun ser campeã em renomear patterns , esse nome é novo pra mim, apesar da composição obvia, e não encontro referencias em outros lugares).
PS: o King costuma dizer que o Hibernate é quem faz o papel do DataMapper, nao o DAO, mas sinceramente se formos dar atenção a como cada um usa a nomenclatura, vamos achar 100 opções diferentes.
This message was edited 1 time. Last update was at 03/08/2009 01:45:56
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 06:31:54
|
Ferryman
JavaGuru
![[Avatar]](/images/avatar/2e3907cbad887e6a1bea84d450b756db.jpg)
Membro desde: 26/10/2006 16:30:23
Mensagens: 220
Offline
|
Concordo com a idéia de que o entityManager faz o papel de DataMapper.
Eu gosto de criar uma camada (Que não vou chamar de DAO), onde isolo o uso do entityManager e as queries do negócio.
Faço isso para manter o SRP (Single Responsability Principle). Esse isolamento ajuda muito nos testes unitários, pois eu posso mockar essa camada inteira e testar apenas a lógica da aplicação, sem precisar subir um banco de dados/hibernate para testes (o que aumentaria consideravelmente o tempo de execução dos testes).
Concordo com a opinião que nunca mudei de tecnologia de persistencia durante um projeto, porém, crio essa camada não com o objetivo de poder mudar a tecnologia, mas sim com o objetivo de manter "cada coisa no seu lugar" - Cada camada com sua responsabilidade.
[]s
|
Rafael Farias Silva (@rafaferry)
Jsigner - Engenharia reversa automática através do maven. Acesse http://code.google.com/p/jsigner |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 08:45:59
|
rponte
JavaEvangelist
![[Avatar]](/images/avatar/37a90a1fe7512a804347fa3e572c6b86.png)
Membro desde: 18/02/2008 10:06:25
Mensagens: 413
Offline
|
Olá Paulo,
Eu concordo com o Leonardo e com o Lazarotti, DAO ainda tem seu lugar e não morreu por causa do JPA.
Basicamente DAO tem seu lugar ainda nas aplicações e deveria ser utilizado nos casos em que faz sentido. O problema, na minha opinião, é que o pessoal tende a replicar DAOs por todos os lugares da aplicação, principalmente para CRUDs e relatórios quando na verdade o DAO está atuando apenas como um wrapper.
Uma coisa que ainda não me entra na cabeça é ter uma DAO layer para tentar abstrair a tecnologia (como citado pelo Lazarotti). Quando se decide por uma tecnologia como JPA/Hibernate você deveria se preocupar mais em aproveitar os recursos da tecnologia a evita-los pelo simples fato de achar que futuramente você poderá mudar de tecnologia.
|
Rafael Ponte
http://www.rponte.com.br/ |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 10:02:20
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Oi Rafael
Vendo seu blog, que no ultimo post fala de DAO, voce comenta que algumas pessoas argumentam assim:
Ah! para abstrair a camada de persistência. Assim se futuramente for necessário mudar de JPA para qualquer outra tecnologia, como JDBC puro, vai ser bem simples, pois bastaria criarmos outra implementação.?
Concordo totalmente que esse não deve ser a justificativa essencial para um DAO. Se só posso nomear como DAO alguem que vai me abstrair se uso JDBC/JDO/JPA, realmente nao chamaria minha classe de DAO, e sim de alguma outra coisa (ModelFacade? como o Alessandro linkou pro beta do catalogo de patterns do Java EE 5).
Acho legal um trecho do wikipedia, que fala As is common in Java, there are many open source and commercial implementations of DAO available. Each of these can have potentially different implementation strategies and usage models. There is a familiarisation curve involved with each of them, realmente cada um faz de um jeito e leva o pattern de um lado pro outro.
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 10:06:42
|
Leozin
JWizard
![[Avatar]](/images/avatar/5dca4c6b9e244d24a30b4c45601d9720.png)
Membro desde: 18/06/2005 21:01:26
Mensagens: 2310
Localização: São Paulo/SP
Online
|
Sinceramente eu não concordo que DAO deva existir depois do JPA.
Criar classes que estão basicamente sendo tratadas como delegates (como DAOs JPA-based) chega a ser uma maneira de "socar" camadas no sistema, aumentando a complexidade e deixando as classes com excesso de coesão. Não que eu ache que coesão seja algo ruim, pelo contrário, mas quando as definições ficam assim,"forçadas demais", dá a impressão que o sistema fica meio feio, sei lá.
Querendo ou não, os EntityManagers já atuam como DAOs genéricos.
Além disso, temos a interface EntityManger que é facilmente "stubável" ou "mockável", eu poderia citar que as vantagens de se utilizar DAOs era a facilidade de ser unit-tested, mas pelo visto não há tantas diferenças não.
Agora, se há chances do sistema trocar de ORM pra JDBC ou qualquer outra coisa, aí sim pode ser que seja necessário criar DAOs. O problema é que nem sempre é assim e o pessoal gosta de se preocupar com apocalypses que mal foram previstos, é como aquela palestra que teve no falando em Java, sobre as "leis" do arquiteto, algo como "se preocupar com performance quando não se há necessidade", apesar das coisas serem completamente diferentes, a idéia de se preocupar com algo que nem se sabe se haverá é a mesma.
Pela experiência que tive até hoje, o que eu concluí foi isso. Já trabalhei com sistemas multibanco, usando DAO com JPA mas não achei muiiiitas vantagens não.
|
http://www.leozin.com.br/blog |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 10:38:05
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Oi Leozin
mas entao onde voce colocaria um método que envolve "data logic"? por exemplo para criar um objeto para diversos relatórios, que é uma combinação de dados de diversas entidades?
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 10:45:57
|
qmx
JavaGuru
Membro desde: 14/02/2007 10:49:14
Mensagens: 212
Localização: Sampa
Offline
|
Eu ainda sou defensor dos DAOs, principalmente pela questão de facilitar os mocks na hora dos testes.
Um efeito colateral bom que eu já peguei, foi uma mudança de tecnologia (sim, muito tosca), que jogou parte do que estava no banco pra um GED. Como já tinhamos DAOs (bem magros por sinal), bastou mudar a implementação.
Acho que o tempo perdido é muito pequeno em vista do benefício, então....
IMHO, sempre
This message was edited 1 time. Last update was at 03/08/2009 10:46:34
|
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 11:25:03
|
rodrigoy
GUJ Ranger
![[Avatar]](/images/avatar/cf79ae6addba60ad018347359bd144d2.jpg)
Membro desde: 18/04/2006 01:06:28
Mensagens: 758
Localização: São Paulo
Offline
|
Paulo, o que tenho aplicado é usar Repositórios como interfaces (só para se beneficiar de DI) e com uma implementação que depende do EntityManager. Abandonei o nome DAO, pois o padrão significa mapeamento para o banco, e como o Hibernate faz isso para nós não vejo sentido em usar essa nomenclatura.
Para falar a verdade, estou para blogar sobre Repositórios... vou ver se adianto isso hoje e aí posto aqui para colaborar...
|
Rodrigo Yoshima
www.ASPERCOM.com.br
Próximas Turmas:
São Paulo: Scrum 28/agosto | OOAD-UML 13/setembro
Débito Técnico Blog: blog.aspercom.com.br
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 11:27:36
|
Leozin
JWizard
![[Avatar]](/images/avatar/5dca4c6b9e244d24a30b4c45601d9720.png)
Membro desde: 18/06/2005 21:01:26
Mensagens: 2310
Localização: São Paulo/SP
Online
|
Paulo Silveira wrote:Oi Leozin
mas entao onde voce colocaria um método que envolve "data logic"? por exemplo para criar um objeto para diversos relatórios, que é uma combinação de dados de diversas entidades?
O ideal mesmo era colocar um repository no teu service, algo de "nível mais alto" se não quiser misturar "tanto" persistência com negócios.
Isso se tu quiser abstrair mais ainda, porque o EM já abstrai muitas coisas na minha opinião, ainda mais se tu trabalhar com NamedQueries por exemplo.
|
http://www.leozin.com.br/blog |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 12:05:41
|
YvGa
Virtual Machine Man
Membro desde: 07/03/2007 15:58:16
Mensagens: 517
Offline
|
Paulo Silveira wrote:Oi Leozin
mas entao onde voce colocaria um método que envolve "data logic"? por exemplo para criar um objeto para diversos relatórios, que é uma combinação de dados de diversas entidades?
Pois é, esse é o ponto.
Eu tbm nao concordo em ter toda aquela hierarquia DAO como propunha o padrao a principio. Mas será que é uma boa ter o codigo de acesso aos dados (Session, EntityManager, etc...) misturado as regras?
Eu tbm vou pelo caminho dos repositorios, mas as ideias que rechaçam os DAOs tbm nao podem ser aplicadas aos repositorios? Afinal eu nao estaria criando uma camada pra, em grande parte dos casos, somente traduzir os metodos do EntityManager.
Mas especifamente esse exemplo que vc deu , eu acho que torna clara a razao da existencia de um repositorio.
This message was edited 1 time. Last update was at 03/08/2009 12:07:17
|
Paulo Borio |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 03/08/2009 12:14:37
|
diegosantiviago
JavaGuru
Membro desde: 14/12/2008 11:53:44
Mensagens: 221
Localização: BR
Offline
|
acho que não devemos esquecer os principios do padrão de projeto DAO.
Context
Access to data varies depending on the source of the data. Access to persistent storage, such as to a database, varies greatly depending on the type of storage (relational databases, object-oriented databases, flat files, and so forth) and the vendor implementation.
Fonte:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
|
SCJA, SCJP, SCBCD, SCEA (I), IBM SOA, ITIL v3 |
|
|
 |
|
|