JPA sem DAO

Houve uma peleja essa semana e gostaria de extender o assunto ao forum para ver a opinião de outras pessoas.

Você deixaria de lado suas classes DAO e utilizaria apenas o EntityManager injetado diretamente em suas classes de negócio?

O objetivo e colher mais opiniões, argumentos a favor e contra e quem sabe algum case.

Grande Igo,

Tá aí minha opinião:

As classes de negócio não devem criar esse mapeamento com o meio de armazenamento, esse papel de fazer o mapeamento dos objetos para qualquer tipo de armazenamento, seja tabelas, xml, csv, é do DAO. Os objetos de negocio não devem nem conhecer como os objetos estão sendo armazenados, e sim conhecer só repositorios. E o DAO ficar sendo a implementação de um Repositório.

[]'s

Primeira verdade universal, até prova em contrário:
“DAO não é repositório.”

Repositório, até onde eu sei, serve para buscar objetos, cujos parâmetros devem ser objetos do tipo Criteria, e só. Um DAO está mais para registro que repositório.

Segunda verdade universal, até prova em contrário:
“DAO e mapeamento OR não combinam, pois o primeiro cria contratos orientado a dados e o segundo, a objetos.”

Em um mapeamento OR, só existem conceitos como objeto gerenciado e objeto não-gerenciado. Tentar mapear isso para um DAO clássico do tipo CRUD pode ser simplesmente uma dor de cabeça, uma vez que, uma possível implementação de DAO seria dar “detach” dos objetos a serem retornados e depois dar “merge” nos objetos recebidos como parâmetros (é até possível não fazer isso, mas isso implica que o DAO não é o único a fazer alteração de estado na base de dados). Não usar DAOs, deixar que o fim de um request e o começo de um outro façam o “detach” para você, e contar com recursos transacionais do Spring ou do EJB podem ser a melhor alternativa.

Nesse post tem uma boa explicação sobre DAO’s e Repositorios.
http://blog.fragmental.com.br/2007/03/01/voce-pergunta-001-daos-e-repositorios/

[]'s

Com certeza isso aqui também vai te ajudar a entender melhor a diferença entre repositórios e DAOs,
http://fragmental.tw/2007/11/29/repositories-misunderstandings/

Já que vocês citaram o Shoes, repitam comigo :slight_smile:

Repeat After Me: Repositories Aren?t DAOs
http://fragmental.tw/2008/04/25/repeat-after-me-repositories-arent-daos/

“Desta forma o DAO pode se tornar a implementação do Repositório.”

Fonte: http://blog.fragmental.com.br/2007/03/01/voce-pergunta-001-daos-e-repositorios/

Opa! Primeiro post no fórum.

Eu não faria isso porque criaria uma dependência imensa com JPA e limitaria a padronização do uso de outras tecnologias ou frameworks para acesso a dados, como JDBC ou Hibernate. Se numa mesma aplicação há a possibilidade de se usar mais de uma opção, uma abstração como um DAO seria extremamente necessária.

Porque usar mais de uma alternativa? Vai depender do cenário. Se existir a necessidade de performance extrema, porque não usar JDBC com uma consulta nativa e bastante otimizada? O benefício pode valer a pena. Ou efetuar uma chamada a uma stored procedure? Aí é caso a caso.

Então, com relação ao post: sim, eu usaria uma abstração. Agora, se essa abstração seria DAO ou Repository, aí vai depender da moda que você vai querer seguir. Só digo uma coisa: DAO e Repository foram separados no parto. A diferença é semântica.

Sabe a diferença entre EMO e Punk?

assunto polemico!
eu nao aconselho, mas tem nomes fortes da comunidade que tem apoiado a ideia… acho que aquele adam bien é um deles

Higor / Igor,

Um outro ponto que eu deveria ter falado no post anterior que tem algo a ver com a minha opinião sobre necessidade de abstração.

Com relação a JPA, sinceramente, eu não entendi a idéia dos responsáveis, ou melhor eu entendi, só não quis acreditar. Lembro-me que quando JPA saiu, vi em algum lugar algo assim: “Pegamos as melhores idéias dos frameworks de persistência e criamos JPA”.

Quando fui ver com mais cautela, percebi que JPA era (ainda é) uma versão enxugada do Hibernate e do TopLink. Os recursos mais úteis, como ‘query by example’, uma API semelhante à de Criteria ou Projections, simplesmente não existem.

Em algumas andanças por aí, percebi que as empresas começaram a adotar JPA, mas implementando dentro de casa a parte que faltava. Em casos piores, usavam o Hibernate como implementação, mas se recusavam a usar seus recursos.

Eu sei que JPA vai melhorar. Muitas coisas boas virão, mas um mecanismo desses não era novidade no mercado. Porque faze-lo tão pobre?

As perguntas são: porque usar JPA? Qual o benefício? Realizar horas de busca no Google? Consumir mais horas de projeto para fazer o mesmo?

Uma abstração poderia te fornecer a oportunidade de usar o mecanismo padrão, mas usando o melhor de cada implementação, quando for necessário. Quando JPA tiver pronta para o mercado, aí é só fazer alterações mínimas só naquela camada.

Acho que é isso.

[]'s

acredito que umas das vantagens seria o fato de estar usando uma especificação.

Eu bem que era a favor de eliminar os DAO’s (e/ou Repositorio) por completo. Só acho que o JPA deixa um pouco a desejar neste sentido. JPA + CRUD está legal, só que queries ainda acaba deixando rastros de (hql/jpql) no seu domínio. Uma API de Criteria/Query Object integrado ao JPA tornaria essa discussão bem interessante, mas por enquanto, se o foco é ter um dominio bem legalzinho, sugiro utilizar DAO e/ou Repositorio.

Um dos motivos de eu antigamente apoiar a eliminação dos DAO’s era simplesmente diminuir burocracia e dar uma alavancada na produtividade. Felizmente, hoje, com repositório (depois de entender melhor o padrão) consigo uma produtivadade ao meu ver bem melhor, já que não dependo de base de dados e persisto em memória. No final, repositorio é um padrão que deixa claro que não dependo nem um pouco da evolução do JPA. :wink:

acredito que umas das vantagens seria o fato de estar usando uma especificação.[/quote]

Rafael, você está certo, mas isso não deveria ser suficiente para adotar uma solução. Ainda prefiro um conjunto de boas práticas e outras coisas mais pontuais para resolução de problemas.

[]'s

com certeza Tarso, isso seria uma das vantagens, a tb outras vantagens além das desvantagens claro.

Encontro um ponto positivo na produção de uma aplicações com DAO.

Podemos ter pessoas especializadas em buscar informações
armazendas (xml, banco de dados, txt) no contexto da aplicação,
que se preocupam apenas com a persistencia de informação, enquanto
a outra parte da equipe desenvolve visões e objetos de negocio.

Visando a parte de produção acho que é um ponto positivo, o uso do DAO.

Em relação ao uso de JPA e suas anotações, é muito bom,
é prático desenvolver, não sou especialista no assunto,
mas na maioria das vezes que usei JPA, usei também um DAO responsavel
por Entidade.

--------
Simple words!
-----------

[quote=higorcoelho]Houve uma peleja essa semana e gostaria de extender o assunto ao forum para ver a opinião de outras pessoas.

Você deixaria de lado suas classes DAO e utilizaria apenas o EntityManager injetado diretamente em suas classes de negócio?

O objetivo e colher mais opiniões, argumentos a favor e contra e quem sabe algum case.[/quote]

O EntityManager é um implementação do padrão DomainStore. Um DomainStore utiliza um DAO dentro dele. Logo, o DomainStore é algo “maior” que um DAO. Logo um DAO nunca deve conter um DomainStore. Então, se for usar o EntityManager utilizar DAO é um sinal da sua incompreensão de arquitetura de sistemas e padrões de projeto.

Então, se quiser utilizar EntityManager não utilize DAO. Se quiser usar DAO, não utilize EntityManager.

Se o EntityManager deve ser injetado nas classes… depende. Para pesquisas não. Devem passar pelo Repositorio apropriado. Para atualizações pode até colocar, mas pode igualmente utilizar o Repositorio para isso caso queira.
Aqui não é muito critico já que em tese vc está invocando o EntityManager de dentro de um serviço ou façade , logo, caso necessário pode ser alterado sem afetar o resto da aplicação.

Pensei em levantar o assunto na lista depois de uma conversa com um ex-colega de trabalho (que hoje so quer saber de RIA e pensei que ele participaria desta discussão).

A discussão esta muito boa e no inicio não quis expor minhas opiniões para não direcionar a discussão deixando ela fluir naturalmente.

Na hora eu defendi o DAO mas depois fiquei me questionando para saber se não estava sendo muito radical. Sei que a JPA tem muita coisa pra evoluir, falta busca por exemplos, criterias e tudo mais.

Ele defendeu o uso da JPA sem o DAO usando a seguinte argumentação: “me parece que JPA é mais pratico usar quando posso garantir que meu acesso será apenas a uma base relacional, enquanto o DAO me permite mais flexibilidade, mas se agora nós temos a JPA pra abstrair o acesso a bancos de dados relacionais, ainda faz sentido implementar os famosos DAOs ou o negócio é meter EntityManager direto em código? Sem falar que com a JPA estou seguindo a especificação, diminuo a burocracia e alavanco a produtividade”.

[quote=higorcoelho]
Ele defendeu o uso da JPA sem o DAO usando a seguinte argumentação: “[…]Sem falar que com a JPA estou seguindo a especificação, diminuo a burocracia e alavanco a produtividade”.[/quote]

Isso não é verdade pela razão já apontada aqui. o JPA não é uma especificação completa.
O JPA trabalha como um DomainStore mas faltam-lhe capacidades de pesquisa desacoplada. O Hibernate já tem isso, então, em tese para ser menos burucrático e mais produtivo deveria usar Hibernate.

Todo o ponto destas conversas é só um : A aplicação NUNCA deve conhecer o sistema de persistencia do seu estado. Quando isso não é isolado o suficiente e ela conhece, o dano está feito. Então o que ha a decidir é o nivel de isolamento da persistencia ( alterações+pesquisa) e ir conforme a decisão.

Desacoplamento Total = Entidades não Anotadas + Repositorio + QueryObject + interface DAO agnostica + Implementação do DAO para a API escolhida.

Acoplamento Total = Entidades anotadas + DAO especifico de negocio e da API escolhida.

Fazer bem não demora mais, apenas tem mais niveis e é preciso mais cuidado com as interfaces dos métodos e a implmentação. Fazer rápido fica pronto antes mas sofre na hora de manter e evoluir.

[quote=sergiotaborda][quote=higorcoelho]Houve uma peleja essa semana e gostaria de extender o assunto ao forum para ver a opinião de outras pessoas.

Você deixaria de lado suas classes DAO e utilizaria apenas o EntityManager injetado diretamente em suas classes de negócio?

O objetivo e colher mais opiniões, argumentos a favor e contra e quem sabe algum case.[/quote]

O EntityManager é um implementação do padrão DomainStore. Um DomainStore utiliza um DAO dentro dele. Logo, o DomainStore é algo “maior” que um DAO. Logo um DAO nunca deve conter um DomainStore. Então, se for usar o EntityManager utilizar DAO é um sinal da sua incompreensão de arquitetura de sistemas e padrões de projeto.

Então, se quiser utilizar EntityManager não utilize DAO. Se quiser usar DAO, não utilize EntityManager.

Se o EntityManager deve ser injetado nas classes… depende. Para pesquisas não. Devem passar pelo Repositorio apropriado. Para atualizações pode até colocar, mas pode igualmente utilizar o Repositorio para isso caso queira.
Aqui não é muito critico já que em tese vc está invocando o EntityManager de dentro de um serviço ou façade , logo, caso necessário pode ser alterado sem afetar o resto da aplicação.[/quote]

Sergio,

Não criando classes DAO, onde ficaria querys especificas? No próprio Facade ou Services?

[quote=sergiotaborda][quote=higorcoelho]
Ele defendeu o uso da JPA sem o DAO usando a seguinte argumentação: “[…]Sem falar que com a JPA estou seguindo a especificação, diminuo a burocracia e alavanco a produtividade”.[/quote]

Isso não é verdade pela razão já apontada aqui. o JPA não é uma especificação completa.
O JPA trabalha como um DomainStore mas faltam-lhe capacidades de pesquisa desacoplada. O Hibernate já tem isso, então, em tese para ser menos burucrático e mais produtivo deveria usar Hibernate.

Todo o ponto destas conversas é só um : A aplicação NUNCA deve conhecer o sistema de persistencia do seu estado. Quando isso não é isolado o suficiente e ela conhece, o dano está feito. Então o que ha a decidir é o nivel de isolamento da persistencia ( alterações+pesquisa) e ir conforme a decisão.

Desacoplamento Total = Entidades não Anotadas + Repositorio + QueryObject + interface DAO agnostica + Implementação do DAO para a API escolhida.

Acoplamento Total = Entidades anotadas + DAO especifico de negocio e da API escolhida.

Fazer bem não demora mais, apenas tem mais niveis e é preciso mais cuidado com as interfaces dos métodos e a implmentação. Fazer rápido fica pronto antes mas sofre na hora de manter e evoluir.[/quote]

Não quero ser chato, mas vc está sendo xiita. Esquece essa meu. Isso contamina os mais novos, porém, me diz, como vc torna isso prático? Como isso não vai tomar mais o tempo de desenvolvimento? No que ganho a longo prazo?
O Hibernate não implementa a JPA atoa. Vc acha que ele sem JPA vai ser o futuro?
Nada começa completo mas, porém, evolui. Aliás, em Java, tudo é mais lento mesmo. Pior ainda qdo querem fazer a coisa mais “desacoplada” que existe.
Eu uso o Spring, JPA, Hibernate com DAO genérico e pronto. Fica fácil de manutenir e mais simples de entender.