Por que usar Hibernate é melhor do que DAO + JDBC?

  • Lazy loading ?

  • Cache ?

  • Herança ?

  • Não ter que fazer os selects na mão ?

  • Referencia cruzada ?

E desde quando usar Hibernate impede você de usar DAO?

O correto não seria perguntar “Porque usar Hibernate é melhor do que JDBC?”?

[quote=Maurício Linhares]E desde quando usar Hibernate impede você de usar DAO?

O correto não seria perguntar “Porque usar Hibernate é melhor do que JDBC?”?[/quote]
exatamente o que eu ia falar :smiley:

uso um DAO para esconder a tecnologia de acesso a dados, o resto do meu sistema não tem que saber se eu uso JDBC ou Hibernate, a unica coisa que entra e sai destes daos são objetos do dominio da aplicação, e de vez em quando uma exceção de acesso a dados (estas o spring mascara pra mim, e faz com que também seja transparente a tecnologia que estou trabalhando :smiley: ) :smiley:

Eh.
Maurício te pegou!


Sergio,
Eu tenho um certo domínio de JDBC. Mas acho trabalhoso demais.
O Hibernate tem uma proposta legal de mapeamento O/R. E por isso eu ando estudando essa porra!!! size=9[/size]

Mas ambos nao usam JDBC?

:roll:

[quote=gui]Mas ambos nao usam JDBC?

:roll:[/quote]

Sim, ambos usam.
Quando citaram usar JDBC referiam-se em utilizar a API diretamente invéz de utilizando um Frame Work de persistência o qual habistrai ela.

Sim, vc pode usar DAO com Hibernate. Verdade.

A pergunta então é porque DAO + HIBERNATE ou HIBERNATE puro é melhor do que DAO + JDBC.

PS: Mudei o título do tópico !

Agora sim! :smiley:
O que o Hibernate tem a oferecer que é melhor que DAO+JDBC.

Achei um tutorial (tambem fiquei curioso e fui atras) falando dos propositos
do hibernate acho que isso da uma esclarecida em porque usar hibernate é legal…
:arrow: http://www.laliluna.de/what-is-hibernate.html

Até… :thumbup:
[s]

Dao não serve exatamente pra isso ?

Depois que vc tem o trabalho inicial de fazer o DAO, vc pode usá-lo exatamente como vc usa a session do hibernate.

Acho que aqui que está o ponto importante. Funções avançadas.

Caches podem se tornar complicados, principalmente se vc tem concorrencia acessando o cache, transações, timeout, etc. Mas eu diria que em 80% dos casos um cache para evitar que o seu DAO vá ao banco de dados não é nenhum bicho de sete cabeças. Um artigo muito bom sobre isso foi comentado aqui: http://www.guj.com.br/posts/list/26589.java

As outras featues avançadas como transaction, lazy loading, não são nem um pouco avançadas e podem ser obtidas facilmente.

Conclusão (provavelmente errada): Hibernate te ajuda no cache e te economiza ter que escrever os selects dos seus beans.

Sei lá, eu consigo escrever rapidamente os DAOs dos meus beans usando JDBC. Isso pq já estou acostumado com isso. Por isso que não usei Hibernate no mybooks do Mentawai. E não me arrependi até agora…

Por isso tb que o mentawai tem um pacote não documentado chamado org.mentawai.cache, com vários tipos de cache… :wink:

Implemente Lazy Loading e queries OO (principalmente polimórficas) facilmente.

LazyLoading de verdade. Tipo todas as ligações telefônicas de uma empresa no ano associadas ao objeto empresa.

Implementar um cache é a maior perda de tempo que existe. Eu diria que em 90% das vezes que tive que depurar bugs relacionados a OOM em uma aplicação Java era porque alguém achou que caching era algo trivial.

Fora isso que um software de cache só é viavel de ser desenvolvido se ele for não-transacional, não-coerente e somente leitura.

Caching eu acho que é um das maiores qualidade do hibernate, tenho usado com resultados incríveis cache de entidades, colections e queries.

:smiley: :smiley: :smiley: :smiley: :smiley: Figura !!! :smiley: :smiley: :smiley: :smiley: :smiley:

Empresa Oi tem 3 bilhões de ligação.

Nem vc nem o Hibernate vão poder carregar todas essas ligações numa lista. Seja Lazy Loading, ou seja o que for.

Isso é um problema de tunning de banco de dados, já que terá que haver um belo índice que te permita pegar subsets dessa mundo sem distruir a máquina e/ou parar o banco.

No Oracle tu teria que fazer algo assim:


select * from (select id, from, to, date, duration from calls 
where id_empresa = 2 and date <= sysdate - 10 order by date) where rownum <= 1000;

Daí na próxima paginação tu faria assim:


select * from (select id, from, to, date, duration from calls 
where id_empresa = 2 and date <= sysdate - 10 and date > ULTIMA DATA order by date) where rownum <= 1000;

Tu vai ter que fazer isso na mão para ir pegando de 1000 em 1000.

Como o Hibernate resolve isso ??? Provavelmente em estado padrão, sem maiories configurações, na primeira chamada a getCalls() ele vai tentar puxar tudo do banco e morrer… :slight_smile: hehehehehehe (se não for isso que acontece me perdoem a piadinha…)

Isso é mais uma questão de banco de dados do que de framework de persistencia !!!

Lazy loading não é taao dificil assim shoes, o que eu acho zuado é implementar eager loading, decodificar um resultset com alguns inner e outer join é muito massante.

O que é eager loading ???

Qualquer inner join e outer join é pentelho de se fazer. Seja na hora de construir a query seja na hora de pegar os resultados.

Se o Hibernate faz isso automático pra vc então realmente é uma vantagem… o problema são os efeitos colaterais:

geralmente para inner e outer joins saber usar o índice certo é muito importante. Se vc faz isso na mão vc pode facilmente melhorar sua query, forçando o uso de um índice ou outro, etc. Se tu deixa o hibernate fazer isso, então vc ficou na mão do hibernate e/ou terá que partir para configurações avançadas do bicho e/ou comprar o Hibernate bible e/ou contratar do Gavin para te ajudar. (claro que exagerei um pouco, mas o meu medo é esse…)

O que é eager loading ???

Qualquer inner join e outer join é pentelho de se fazer. Seja na hora de construir a query seja na hora de pegar os resultados.

Se o Hibernate faz isso automático pra vc então realmente é uma vantagem… o problema são os efeitos colaterais:

geralmente para inner e outer joins saber usar o índice certo é muito importante. Se vc faz isso na mão vc pode facilmente melhorar sua query, forçando o uso de um índice ou outro, etc. Se tu deixa o hibernate fazer isso, então vc ficou na mão do hibernate e/ou terá que partir para configurações avançadas do bicho e/ou comprar o Hibernate bible e/ou contratar do Gavin para te ajudar. (claro que exagerei um pouco, mas o meu medo é esse…)

[/quote]

Eager loading é o contrario de lazy loading. E só é necessario se preocupar com indicar os índices nas queries se o teu banco de dados for mongoloide e gerar planos muito ruins. DBAs acefalos também vale. Até hoje as únicas vezes que ví precisarem colocar hints de índices nas queries foi quando o modelo de dados era estrupiado além do imaginavel.

Na minha opiniao, implementação bem rápida de operações CRUD, lazy loading sem macumba e cache fácil são as maiores vantagens (e mais genericas) do Hibernate.

Verdade, já que o meu caso está no extremo oposto. Muito campos, muitos índices, muito peso no banco na hora de fazer as queries. Solução encontrada: replicação de banco em bases read-only de 10 em 10 minutos, ou algo assim que o DBA inventou. Não me lembro. (Isso era a busca do ParPerfeito e o cupido, isto é, pega esses 10 milhões de usuários e me diz quem combina comigo…)

Bom, essa discussão não vai ter fim. O Hibernate é soda, mas eu não sei usar direito e não tenho saco para aprender, principalmente se estiver na secura de terminar logo um projeto.

Alguma alma caridosa (vai ser difícil), poderia migrar o mybooks para Hibernate. Só para se ter um comparativo mais prático entre uma coisa e outra. O mybooks é simples mais tem seus inner joins, e espaço para um cachezinho na busca por livros / usuários…

Eu tou com uma aplicação aqui que gera 3 milhões de consultas em 40minutos, isso de uma máquina apenas, com hibernade reduzi isso para algo em torno de 200mil, e agora ela faz o que foi prometido.

Por causa do cache ? No início eu já falava que o cache do Hibernate deve ser o principal motivo para usá-lo…

[quote=saoj] :
No Oracle tu teria que fazer algo assim:

select * from (select id, from, to, date, duration from calls 
where id_empresa = 2 and date <= sysdate - 10 order by date) where rownum <= 1000;

Daí na próxima paginação tu faria assim:

select * from (select id, from, to, date, duration from calls 
where id_empresa = 2 and date <= sysdate - 10 and date > ULTIMA DATA order by date) where rownum <= 1000;

Tu vai ter que fazer isso na mão para ir pegando de 1000 em 1000.
Como o Hibernate resolve isso ??? Provavelmente em estado padrão, sem maiories configurações, na primeira chamada a getCalls() ele vai tentar puxar tudo do banco e morrer…
[/quote]

1º:

s.createCriteria(Call.class)
    .add(Restrictions.eq("empresa.id", 2))
    .add(Restrictions.lt("data", new Date())
    .setMaxResults(1000)
    .list();

Então:

s.createCriteria(Call.class)
    .add(Restrictions.eq("empresa.id", 2))
    .add(Restrictions.lt("data", new Date())
     setFirstResult(1001)
    .setMaxResults(1000)
    .list();

Okay.