Hibernate + DAOs: qual a vantagem?

Conforme descrito aqui, DAOs são interessantes para abstrair fontes de dados, facilitando dessa forma a troca de uma fonte no futuro.

O hibernate, através do HQL e de suas configurações de driver, permite que eu troque facilmente uma fonte de dados.

A pergunta é: pq algumas pessoas usam hibernate + DAOs ? Não consegui até então encontrar um bom motivo e agradeceria se alguém conseguisse me mostar quais as vantagens.

Um não atrapalha o outro, o DAO é um pattern que serve para abstrair a camada de persistência.

no seu método você vai fazer algo como:public void gravarPessoa(Pessoa pessoa){ PessoaDAO dao = new PessoaDAO(); dao.gravar(pessoa); } Agora o que vai acontecer dentro do DAO? Não importa nessa hora, aí é que está, ali dentro a persistência pode ser feita com Hibernate, com JDBC, com o que você quiser. Entendeu?

O que eu tenho visto por aí é mais uma questão de organização, padronização, do que efetivamente necessidade de troca de fonte de dados. Aliás, se esse é o único argumento para usar um framework ORM, sugiro rever os conceitos, pois, até o presente momento, eu não vi um projeto mudar de banco de dados.
Alguns programadores se acostumaram ao padrão DAO, ele é facilmente adaptado à outros patterns e permite um bom uso de polimorfismo (você cria uma interface ou um abstract class e os DAOs específicos são facilmente utilizados).

Se você não vê com bons olhos esse uso, qual a tua sugestão?

[quote=digaoneves]Um não atrapalha o outro, o DAO é um pattern que serve para abstrair a camada de persistência.

no seu método você vai fazer algo como:public void gravarPessoa(Pessoa pessoa){ PessoaDAO dao = new PessoaDAO(); dao.gravar(pessoa); } Agora o que vai acontecer dentro do DAO? Não importa nessa hora, aí é que está, ali dentro a persistência pode ser feita com Hibernate, com JDBC, com o que você quiser. Entendeu?[/quote]
Indo além, o sistema com o qual trabalho durante o dia emprega Struts 1 e o pattern facade, sem DAOs, toda a lógica é feita por classes Core, “escondidas” pela fachada.
Dentro das Core, cria-se o código SQL e executa-se a partir de uma Session estabelecida por Hibernate.
Isso poderia ser adaptado para DAO, sem perda de performance ou mesmo de pattern.
Se é o mais indicado, não posso afirmar, é a primeira vez que uso tal modelo.
O que digo é, mantém uma empresa que fatura mais de R$ 25 milhões/dia.

Mas não vejo vantagem, é mais fácil usar um

em.persist(pessoa)

direto em um EJB.

Sem o overhead de criar classes a mais, sem aumentar a complexidade do design (apesar de ser pouca complexidade, é desnecessária).

[quote=drsmachado]O que eu tenho visto por aí é mais uma questão de organização, padronização, do que efetivamente necessidade de troca de fonte de dados. Aliás, se esse é o único argumento para usar um framework ORM, sugiro rever os conceitos, pois, até o presente momento, eu não vi um projeto mudar de banco de dados.
Alguns programadores se acostumaram ao padrão DAO, ele é facilmente adaptado à outros patterns e permite um bom uso de polimorfismo (você cria uma interface ou um abstract class e os DAOs específicos são facilmente utilizados).

Se você não vê com bons olhos esse uso, qual a tua sugestão?[/quote]

Eu já trabalhei em sistemas que tinham que funcionar em mais de um banco de dados (um cliente poderia querer usá-lo com um oracle, e outro com um postgre, por exemplo). Com ajuda do hibernate (e sem DAOs) eu criava módulos diferentes com configurações de hibernate, uma para caba banco. E só.

Acho que dizer que é bom usar pq tdo mundo usa não é um bom argumento, tdo mundo pode estar usando erroneamente.

você prefere persistir dessa maneira em métodos que implementam suas regras de negócio ?

Seu argumento até que é valido, mas não consigo ver uma diferença muito grande entre a sua sugestão (dao.gravar(pessoa)) e a minha (em.persist(pessoa)). No seu caso, o dao cuida da conexão. No meu caso o entitymanager cuida da conexão. Não mudou muito.

[quote=rodpuc]Mas não vejo vantagem, é mais fácil usar um

em.persist(pessoa)

direto em um EJB.

Sem o overhead de criar classes a mais, sem aumentar a complexidade do design (apesar de ser pouca complexidade, é desnecessária).[/quote]

Certo. Aqui não vejo diferenças:

dao.gravar(pessoa);

em.persist(pessoa);

Mas…e nas pesquisas? Terias HQL misturado com as regras de negócio?

[quote=rodpuc]Mas não vejo vantagem, é mais fácil usar um

em.persist(pessoa)

direto em um EJB.

Sem o overhead de criar classes a mais, sem aumentar a complexidade do design (apesar de ser pouca complexidade, é desnecessária).[/quote]
Ok, mas se meu sistema visa matar formigas, por que devo usar um rifle para matar elefantes?
Camarada, você não quer aumentar a complexidade do design, só da implementação, certo?
EJBs são indicados para casos específicos.
Por que eu preciso ter um application server se posso rodar meu sistema, com DAOs e Hibernate, em um Tomcat 6.xxx?

O que eu quero dizer é que cada caso exige uma postura específica.
É um erro comum, quando aprendemos uma tecnologia nova, querer usá-la em todo tipo de situação (lembro-me quando aprendi a criptografar com MD5 em PHP, queria criptografar tudo).
Ou seja, a questão de adicionar uma subcamada de classes (dentro da camada de persistência) é irrisória, perto de instalar um JBoss ou Weblogic ou Websphere ou afins.

Seu argumento até que é valido, mas não consigo ver uma diferença muito grande entre a sua sugestão (dao.gravar(pessoa)) e a minha (em.persist(pessoa)). No seu caso, o dao cuida da conexão. No meu caso o entitymanager cuida da conexão. Não mudou muito.[/quote]

Sim, a diferença é que o em.persist(pessoa) estaria dentro do dao.gravar(pessoa), abstraindo isso pra você.

Se um dia decidirem que ao invés de usar Hibernate/JPA vão usar JDBC pra persistir (duvido que aconteça, mas é um exemplo válido).

Você vai alterar o método dentro do seu DAO, e todas as classes que usam ele não precisam nem saber que a implementação mudou. Se não abstrair isso vai ter que dar um Find/Replace em todos seus em.persist(pessoa) pra seja la qual for o método novo.

[quote=rodpuc][quote=drsmachado]O que eu tenho visto por aí é mais uma questão de organização, padronização, do que efetivamente necessidade de troca de fonte de dados. Aliás, se esse é o único argumento para usar um framework ORM, sugiro rever os conceitos, pois, até o presente momento, eu não vi um projeto mudar de banco de dados.
Alguns programadores se acostumaram ao padrão DAO, ele é facilmente adaptado à outros patterns e permite um bom uso de polimorfismo (você cria uma interface ou um abstract class e os DAOs específicos são facilmente utilizados).

Se você não vê com bons olhos esse uso, qual a tua sugestão?[/quote]

Eu já trabalhei em sistemas que tinham que funcionar em mais de um banco de dados (um cliente poderia querer usá-lo com um oracle, e outro com um postgre, por exemplo). Com ajuda do hibernate (e sem DAOs) eu criava módulos diferentes com configurações de hibernate, uma para caba banco. E só.

Acho que dizer que é bom usar pq tdo mundo usa não é um bom argumento, tdo mundo pode estar usando erroneamente.[/quote]
Pode-se fazer isso com JDBC e, ainda, customizar as queries de acordo com o tipo de performance de cada banco de dados, sem correr o risco de problemas oriundos do uso de uma biblioteca “estranha” ao java.
Aliás, isso é algo extremamente simples e sequer necessitaria de qualquer artifício diferente de polimorfismo. Bastaria criar uma interface que represente a conexão e, para cada banco, implementar uma classe concreta que faça essas vezes. Mais uma vez, a complexidade passa do design para a implementação. Seguindo a tua lógica, o uso de hibernate traria mais desconforto que qualidade. Porém, cada caso é um caso, como disse anteriormente.

[quote=pmlm]
Mas…e nas pesquisas? Terias HQL misturado com as regras de negócio?[/quote]

Tem razão, é um bom argumento.

[quote=digaoneves]
Sim, a diferença é que o em.persist(pessoa) estaria dentro do dao.gravar(pessoa), abstraindo isso pra você.

Se um dia decidirem que ao invés de usar Hibernate/JPA vão usar JDBC pra persistir (duvido que aconteça, mas é um exemplo válido).

Você vai alterar o método dentro do seu DAO, e todas as classes que usam ele não precisam nem saber que a implementação mudou. Se não abstrair isso vai ter que dar um Find/Replace em todos seus em.persist(pessoa) pra seja la qual for o método novo.[/quote]

Tem razão também, é um bom argumento.