Duvidas sobre Dao + Hibernate + Repository

@Juk

Você sim disse que é a mesma coisa.

Se A implementa B e nada mais, então A é B.
Isto é OO 101.

@Rubem Azenha

O mundo é maior que DDD. Leia sobre o padrão Repository no livro do Fowler e confronte com o padrão DataMapper (DAO) do mesmo livro. Não tem nada a haver com DDD.
O padrão Repository não pertence ao DDD e o nome “Repositorio” em DDD não diz respeito directamente ao padrão “Repository”.

Em DDD um repositorio pode ser qualquer coisa: um list, um DAO, um Map, um EJB, etc…
Em OO, o padrão Repository não pode ser um DAO ou um Map ou um List oum EJB. Ele pode ser composto por um DAO, um map, um list , um EJB…

São coisas totalmente diferentes. Quando se fala em DAO vs Repositorio não estamos em DDD porque em DDD essa diferença é irrelevante.
Quando falamos em DAO vs Repositorio estamos falando de OO e Padrões de Projeto. Estamos falando do Principio de Separação de Responsabilidade.
É um mundo maior que o de DDD.

Então o ponto é : Um objecto construido sob o padrão DAO tem a mesma responsabilidade que um construido sob Reposiotry ?
A resposta é não. Porquê ?

  1. Repositorio tem a responsabilidade primeira de conhecer o dominio. O DAO não.
  2. O DAO tem que conhecer a tecnologia de persistencia. O repositorio não.
  3. O repositorio executa pesquisas próprias ao domino onde os parametros são objetos que representam valores para parametros da pesquisa e nunca a pesquisa em si ( não QueryObjects) . O DAO só executa QueryObjects mas não os monta ( O DAO executa SQL, mas ele não escolhe o SQL)
  4. A implementação de um repositorio contém regras de negocio. A forma como as pesquisas são definidas é um regra. O DAO não contém regras de negocio. Ele executa de forma “burra” um certo comando.
  5. Mais geralmente DAO é um tipo especifico do padrão Service. Repositorio não é um Service.

Um exemplo simples da diferença. nos antigamentes um EJB tinha um home e vc executavas coias como findByXYZ() em cima do Home. A resposta era um objecto do tipo do EJB-Entidade ou uma lista deles. Este home tinha o papel de um repositorio do ponto de vista do resto do core de negocio. Mas era comum vc implementar os EJB-Entity usando um DAO para JDBC. Isto porque era suposto que seria possivel mudar o DAO ( por exemplo, se mudasse de banco). Os AS rápidamente viram que isto era muito chato e esta parte foi automatizada com o CMP. O DAO morreu, mas o Home(o repositorio) não. então :

  1. O reposiotrio nunca morre enquanto o dominio existe. o DAO morre quando a tecnologia de preservação (persistencia ou prevalencia) muda.
    Um DAO é plugável e intercambável. Ou seja, é suposto vc poder titar um JDBCDAO e substituir por um XMLDAO ou um LDAPDAO. Um repositorio não é substituivel. O repositorio não é substituivel pela mesma razão que um entity não é. Não faz sentido vc ter duas implemetações de cliente, ou produto. A unica coisa que faz sentido neste tipo de objeto é o uso do padrão Strategy. JDBCDAO , XMLDAO, etc… não são Strategy, são implementações per-se de DAO ( porque estamos usando o padrão Service no fim de contas).

É claro agora ?

Hum… realmente, se formos pegar a descrição de Repository do Fowler tem outro sentido. Eu estava me referindo a descrição do Eric Evans no seu livro sobre DDD.

Note só que em momento algum ele inviabiliza o uso do DAO\DataMapper e diz que o correto pra usar direto o mecanismo do persistência nas classes de negócio e que no caso, Repository é simplesmente uma camada entre a camada de persistência e a camada de negócios.

[quote=Rubem Azenha]Hum… realmente, se formos pegar a descrição de Repository do Fowler tem outro sentido. (…)

Note só que em momento algum ele inviabiliza o uso do DAO\DataMapper e diz que o correto pra usar direto o mecanismo do persistência nas classes de negócio e que no caso, Repository é simplesmente uma camada entre a camada de persistência e a camada de negócios.[/quote]

Eu alguma vez disse que DAO era inviável ? ou alguma vez disse que o correto é usar directo o mecanismo de persistencia ? Não, pois não ?

Agora que vc entendeu o que é um Repository vamos à segunda parte: porque eu não preciso mais do DAO ?

Antigamente o DAO era usada na arquitetura EJB <= 2 para acessar banco de dados. Este mecanismo realmente teve uma utilidade naquele tempo , mas nunca deslanchou (ninguem implementava daos para mais do que um banco). Os fabricantes de AS, sobretudo o JBoss tiveram a ideia de encapsular esta responsabilidade de uma vez por todas e nasceu o CMP ( Container Managed Persistence). Isto é o incio do fim para o DAO.

O CMP virou o hibernate e o hibernate virou uma API separada. O DAO ainda continua lá, mas por baixo de 7 camadas de tinta.

O Hibernate foi um sucesso e o modelo EJB <=2 foi bombardeado de todos os lados. O odio de xml , exceções mirabolantes, falta de injeção automática de dependencia , etc… levaram ao repensamento do modelo EJB ( um dos melhores modelos já construidos, mas cujas implementações tiveram que se antenar com os tempos)

Ora ai nasceram duas coisas: a visão de que era possivel manipular entidades de uma forma menos intrusiva como o hibernate fazia e que isso estava virando modelo ( o JDO outro candidato a substituir o CMP está ai).
Os JEE Core patterns foram revistos. Muita influencia de padrões como os do Fowler e outros trouxeram nova estrutura. Lembrando que as versões anteriores do EJB foram criada pela SUn mas a EJB 3 foi criada por todos.
O padrão que surgiu para matar o CMP e o BMP foi o DomainStore do qual o hibernate é uma implementação.
Sendo que a sun não poderia oficialmente suportar o modelo do hibernate nasceu a JPA. A JPA é para o DomainStore o que o JDBC é para o DataMapper. Com o mecanismo de providers é possivel ter o hibernate sem o problema de o suportar oficialmente. A JPA não é perfeita. só suporta SQL, mas é um começo. O ponto importante aqui é o DomainStore.

Este novo padrão é complexo. É na realidade um conjunto de padrões orquestrados por baixo de uma API publica simples. A palavra “Domain” aqui tb não tem nada a haver com o DDD. Claro que o “domain” se refere ao mesmo que o DDD , mas não ha influencia. São duas coisas usando o mesmo conceito. O ponto é que este novo padrão precisa ser alimenta com informações do dominio ( do dominio de dados, ok, mas do dominio , non the less)
Para isso as Annotações cairam que nem uma luva embora o XML seja suportado. Porquê ? Primeiro porque as anotações são intrusivas e deixam o mesmo rastro que o CMP e o EJB <=2 , só que de um jeito menos melequento. Segundo porque o hibernate funcionava com XML nas suas versões pre-JPA.

O DomainStore é um DataMapper com conhecimento do dominio. Quão poderoso é isso ? muito poderoso.
Lá no fundinho das 7 camadas de tinta existe o DAO, mas ele é totalmente irrelevante no dia a dia ( a menos que queira implementar JPA para XML… ).

Ok, depois disto acho que é claro que o DAO foi substituido pelo DomainStore. Um padrão mais moderno , mais robusto e mais versátil. O DAO como o conheciamos não é mais relevante. O seu unico uso hoje em dia é para comunicar com sistemas legados.

Então, para aplicações novas Java 6 e tudo isso não se usa DAO, se usa DomainStore, no corpo do Hibernate ou do JPA. Este é o padrão real para as aplicações modernas.

“Ah! mas eu preciso ter uma camada de indireção para poder substituir o Hibernate/JPA por outra coisa” … boa sorte. Primeiro que essa camada de indireção é complexa p’ra caramba de construir e segundo é inútil se usar hibernate/JPA. Porque o domainStore precisa de info do dominio via anotações ou xml ele sempre estará atrelado do dominio. É muito simples. Pegue um sistema que tenha com hibernate e tente colocar uma camada entre ele e o resto. Depois disso tire o hibernate e coloque outra coisa. Consegue ? … e aqueles anotações lá nas entidades ? como substitui isso ? …

Concluindo: não ha necessidade de uma camada de indireção porque nunca você fará uso dela.

Na analise do Fowler para o Repository que tem o papel de concentrar a montagem das queries isso ainda continua. O DomainStore ainda precisa ser “queriable”. Exactamente ai que o Hibernate bate o JPA e por isso que o JPA 2 vem com a Criteria API. Porque precisa colocar a criteria API ? Porque ela é forma natural de pesquisar um DomainStore. Assim o Repositorio que hoje monta SQL ou Hibernate Criteria, amanha montará JPA 2 Criteria. Acima do repositório nada mudou. Dai a sua função de isolador.

No antigamente vc usava JDBC , depois veio o DAO e subimos um nivel de abstração. Hoje tem um DomainStore dois niveis acima. Faz algum sentido colocar o hibernate dentro de um DAO novamente ? é como colocar um pneu de formula 1 dentro de um pedaço de madeira e acoplar numa carroça. Isso não é forma de fazer sistemas modernos.

Não é o Fowler nem minguem que inviabiliza o uso do DAO nas aplicações modernas, especialmente as que usam Hibernate ou JPA (qq outro DomainStore de mercado). É a própria evolução da tecnologia e dos conceitos teóricos por detrás dela. É a própria historia que coloca o DAO na geladeira.

Foi o padrão DomainStore que matou o DAO , não eu, nem o Fowler, nem ninguém.

Aí vai depender que Domain Store você se refere.
Se for ao definido no Core JEe Patterns, não ele só não matou como ainda o utiliza/sugere a utilização do DAO como StoreManager.
http://www.corej2eepatterns.com/Patterns2ndEd/DomainStore.htm

Aí vai depender que Domain Store você se refere.
Se for ao definido no Core JEe Patterns, não ele só não matou como ainda o utiliza/sugere a utilização do DAO como StoreManager.
http://www.corej2eepatterns.com/Patterns2ndEd/DomainStore.htm

[/quote]

Para bom entendedor meia palavra basta.
Acho que é claro que quando eu disse “matou” me referi ao uso pelo programador. Além de que eu falei várias vezes que o DAO continua sendo usado dentro do DomainStore.

O ponto é que o programador não precisa implementar ou invocar o DAO nunca mais.

Antes este fosse o único problema.

Quando desenvolvemos com frameworks como JPA ou Hibernate nós mudamos nossa maneira de trabalhar com os objetos de negócios. Passamos a considerar relacionamentos LAZY e/ou EAGER, contexto de persistência, dirty checking e features interessantes do framework ORM. Isso claro, se estivermos interessados em aproveitar o que o ORM pode nos oferecer de melhor. Além de que algumas features acabam refletindo noutras camadas. como a preocupação quanto a lazy-loading ou não.

Por isso simplesmente substituir a implementação do DAO não funciona como gostaríamos quando trabalhamos com algum ORM decente.

Olá tudo bem, pesquisei durante uma semana e nada, podem me ajudar ?

tenho o seguinte DAO

[code]public class PRT_PROCESSOS_DAO extends GenericDAO {

public PRT_PROCESSOS getProcesso(Integer codEmp, Integer ano, Integer codProc) {
    return (PRT_PROCESSOS) getPurePojo("from PRT_PROCESSOS where processoPK.PRC_CODEMP = ?"
            + " and processoPK.PRC_CODANO = ? and processoPK.PRC_COD = ?", codEmp, ano, codProc);
}[/code]

irei mudar esse select para pegar todos os processos de uma determinada empresa no qual informo via cnpj na tela. Me ajudem a pegar o resultado desse sql que vou fazer e colocar em uma lista para depois eu pegar a lista e por num tabela. Já li sobre listas coleções etc, preciso de um exemplo, nao quero nada pronto só um exemplo pra me basear.

Obrigado