Hibernate - Classe DAO Genérica para persistencia de todos os objetos  XML
Índice dos Fóruns » Java Avançado
Autor Mensagem
root_
JavaGuru
[Avatar]

Membro desde: 05/09/2006 15:46:19
Mensagens: 206
Localização: Gurupi - Tocantins
Offline

Seguite galera, estou implementando um sistema usando hibernate annotations e conheco o Hibernate a pouco tempo!

De todas as literaturas que pesquisei, todas criam uma classe DAO para respectiva classe persistente... então decidi criar uma classe GenericDAO, para controlar a persistencia de todos os objetos da aplicação.

Os códigos seguem logo abaixo:

HiberbateUtil


GenericDAO, Classe que vai controlar a persistencia de todos os meus objetos.



Por enquanto a classe GenericDAO tem apenas essas funcionalidades, mais pretendo deixa-la padrão para uso na persistencia de qualquer tipo de objeto que persistirá no Banco, ao infez de ficar criando classes DAO para controlar cada uma das classes persistentes.
Para quem gostar da idéia ( transcrever as classes acima padronizando-as para qualquer tipo de uso)... estamos ai!!!!

Agradeço desde já!
Abraços!

Rogério Milhomens de Queiroz
Agile - Consultoria em Tecnologia da Informação!
http://www.agilecti.com.br
Dataview - Inteligência em Tecnologia!
http://www.dataview.com.br
[Email] [WWW] [MSN]
Eduardo Bregaida
Moderador
[Avatar]
Membro desde: 13/11/2003 14:11:35
Mensagens: 2416
Localização: São Caetano do Sul - SP
Offline

Opa para complementar vou deixar meu blog com a primeira parte do tutorial de JSF q uso DAO Genérico, com Hibernate e JPA

http://javawora.blogspot.com/2007/06/tutorial-parte-1.html

Tem uma explicação bem passo a passo
Espero ter ajudado

Blog - Java Anywhere
@bregaida - Twitter
Flickr - Fotos
Cursos de Java?

"Você poderia me dizer, por favor, qual caminho eu devo seguir?"
"Isto depende muito de onde você deseja chegar."
-Lewis Carroll, Alice no País das Maravilhas
[Email] [WWW] [MSN]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

alguns comentarios



Vejo que vc não usou generics. Tlv porque quer usar java 1.4 ou anteiror
mas algo que fala ali é controle de exceptions, não ?
Primeiro Exception é demasiado geral para lançar. Segundo deveria lançar uma RuntimeException
Se isso foi escolha sua pense melhor nas opções. Por outro lado fala o controlo de roolback.
Se vc o incluir no metodo não precisa de um método á parte.
Eu pensaria que seria assim:




Tem uma classe Fornecedor aparecendo ali
O parse para integer é redundante.
O metodo não lista nada, ele só traz um elemento. O nome é enganador



Tlv melhor assim



Seria tb bom implementar um método que persista vários objetos na mesma transação

This message was edited 2 times. Last update was at 20/09/2007 12:43:45


Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
rodrigoallemand
GUJ Ranger
[Avatar]

Membro desde: 21/02/2005 20:19:47
Mensagens: 972
Localização: Rio de Janeiro, Recreio!!!
Offline

Bem, eu tenho uma solução generica para DAOs, no Hibernate e no JPA.
Se liga!

Interface de Repositorio Generica...



Interface para Repositorios usando Hibernate



Classe para DAO Hibernate...



Dai em diante, as classes de entidade só extendem essas classes/interfaces...
Com isso:

>> ClienteRepository extends HibernateGenericRepository<Long, Cliente>
>> ClienteDAO extends HibernateGenericDAO<Long, Cliente>

E assim por diante...

Rodrigo Allemand

A culpa é minha e eu a coloco em quem eu quizer!. (Homer Simpson)
http://blog.rodrigoallemand.com.br
[WWW] [MSN]
ddduran
Virtual Machine Man
[Avatar]

Membro desde: 13/11/2006 16:44:54
Mensagens: 523
Offline

Bom vamos la abaixo minhas humildes considerações

Que tal um pouco de IoC ai?

não acho que seja responsabilidade do seu dao ir abrir ou fechar a sessão,
você poderia colocar essa dependência no construtor, algo como seu código ter um construtor assim:



até por que você não reparou que você repete esse codigo



umas vinte vezes?
fora que ai você comete um erro terrível, você começa e termina uma transação dentro do seu DAO, sua implementação atual só permite
que eu faça uma ação por transação, eu não poderia por exemplo incluir um cliente depois uma unidade de negocio na mesma transação pro caso de ocorrer um erro na unidade de negocio eu desfazer a inserção do cliente.

da uma olhada nisso http://www.hibernate.org/43.html

outro comentario, não é um Dao generico? então abuse de generics

rmarin
JavaEvangelist
[Avatar]

Membro desde: 13/07/2005 09:14:45
Mensagens: 360
Localização: São Paulo
Offline

Outra coisa que precisa ser revisada é o "throws Exception" em tudo que é método...

Roberto Marin
__________________________________________
Odeio auto-nerds!
[WWW]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

rodrigoallemand wrote:Bem, eu tenho uma solução generica para DAOs, no Hibernate e no JPA.


Achei interessante a sua abordagem. Fiquei curioso para saber o que são (para que servem)
ScopeType e CriteriaType.

Outra coisa, é ID (Identifier) ou PK (Primary Key). Podemos pensar que não são a mesma coisa
Identifier : atributo privado que identifica univoca e globalmente o objeto.
PrimaryKey : atributos e/ou conjunto de atributos que identificam univocamente o registro.

Se o repositorio é genérico porque precisa criar ClienteRepository, etc.. ? Um HibernateRepository não basta ?


Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
rodrigoallemand
GUJ Ranger
[Avatar]

Membro desde: 21/02/2005 20:19:47
Mensagens: 972
Localização: Rio de Janeiro, Recreio!!!
Offline

sergiotaborda wrote:
Achei interessante a sua abordagem. Fiquei curioso para saber o que são (para que servem)
ScopeType e CriteriaType.


ScopeType é porque, onde foi implementado esse Framework, nós temos dois modelos de banco de dados, onde um não há o esquema de transação (Commit e Roolback). Com isso, vc cria um enumeration com os escopos disponiveis para que saiba onde commitar. No caso de um banco relacional com controle de transação (um Oracle da vida) esse enumeration pode ser do tipo:

Local: A cada método é aberto uma transação que é confirmada ao fim do método, independente se existem mais coisas sendo feita.
Filter: Deixa que o InterceptingFilter se vira
Request: Parecida com o Filter, mas focada em processos. No nosso Framework, um processo pode chamar outro processo, criando um evento...

E alguns outros tipos

Já o CriteriaType é, esperando a versão 2 do JPA onde se Deus quizer teremos critérios como no Hibernate. Com isso, a montagem de critérios é generica... não monstrei os metodos onde isso acontece... segue exemplo.



sergiotaborda wrote:
Outra coisa, é ID (Identifier) ou PK (Primary Key). Podemos pensar que não são a mesma coisa
Identifier : atributo privado que identifica univoca e globalmente o objeto.
PrimaryKey : atributos e/ou conjunto de atributos que identificam univocamente o registro.


Eu utilizo ai a classe que vc definiu como ID da entidade... mas resolvemos colocar o nome de Pk por facilidade de assimilação com o antigo frameowrks... Mas seria um ID do Hibernate ou do JPA por exemplo...

sergiotaborda wrote:
Se o repositorio é genérico porque precisa criar ClienteRepository, etc.. ? Um HibernateRepository não basta ?


Poderia se vc utilizasse uma outra classe que existe no framework, que é a ObjectRepository extends HibernateGenericRepository <Objetc, Object>...
A ideia é especializar mais as classes sem criar métodos... Fazendo o que vc sugeriu (e é totalmente válido) é ter os repositorios por entidade, extendendo as interfaces sem necessidade de criação de nada mas retornando e recebendo os dados corretos para cada entidade, garantindo possiveis erros...

E se vc quizesse, no meio do projeto, criar o método sbrubleCliente()? Ai sim vc teria que criar uma interface para o repositorio de cliente e refatorar seu código para utilizar tal interface, extendendo de HibernateGenericRepository etc.... Porque não criar logo essa interface, extrendendo do lugar correto?
Nós temos um gerador de código para isso... ai a aplicação já vem na estrutura certinha pra isso...

This message was edited 1 time. Last update was at 20/09/2007 15:27:50


Rodrigo Allemand

A culpa é minha e eu a coloco em quem eu quizer!. (Homer Simpson)
http://blog.rodrigoallemand.com.br
[WWW] [MSN]
J2Alex
JavaEvangelist
[Avatar]

Membro desde: 18/01/2003 08:14:41
Mensagens: 348
Localização: São José dos Campos
Offline

Controle de transação não tem nada a ver com DAO.

Alexandre



Hoje tem Balada
https://apps.facebook.com/hojetembalada
Guia colaborativo de baladas, bares e restaurantes
[WWW]
rodrigoallemand
GUJ Ranger
[Avatar]

Membro desde: 21/02/2005 20:19:47
Mensagens: 972
Localização: Rio de Janeiro, Recreio!!!
Offline

J2Alex wrote:Controle de transação não tem nada a ver com DAO.


Concordo e essa foi uma duvida levantada no desenho da aplicação... apesar de que em 100% dos casos isso ficar no Intercepting Filter, ou seja, nem no DAO e nem das classes de negocio... mas por uma experiencia passada, resolvemos colocar esse marcador dentro do DAO...
Mais hoje em dia eu acho que a ordem do Commit tá mais pra DAO do que pra BO...

This message was edited 1 time. Last update was at 20/09/2007 16:27:21


Rodrigo Allemand

A culpa é minha e eu a coloco em quem eu quizer!. (Homer Simpson)
http://blog.rodrigoallemand.com.br
[WWW] [MSN]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

rodrigoallemand wrote:

Já o CriteriaType é, esperando a versão 2 do JPA onde se Deus quizer teremos critérios como no Hibernate. Com isso, a montagem de critérios é generica... não monstrei os metodos onde isso acontece... segue exemplo.





entendi. Mas se o DAO é genérico não deveria os Criteira tb ser ?
Ou seja, a interface deveria ser apenas:



Aquele Criteria não é o do Hibernate. É um objeto que contém a query em forma de grafo que cada dao irá converter. No caso do Hibernate do futuro JPA vc converte para o objeto Criteria deles. Para um DAO JDBC puro vc converte direto para SQL.

Ok, eu sei que da ideia à prática vai um pedaço. No framework que eu uso é usada esta estratégia. Como o DAO é puro JDBC o mapeamento é direto para SQL e funciona bem.
(Entende-se que com um mecanismo assim o Hibernate/JPA tem poucas vantagens)


sergiotaborda wrote:
Outra coisa, é ID (Identifier) ou PK (Primary Key). Podemos pensar que não são a mesma coisa
Identifier : atributo privado que identifica univoca e globalmente o objeto.
PrimaryKey : atributos e/ou conjunto de atributos que identificam univocamente o registro.


Eu utilizo ai a classe que vc definiu como ID da entidade... mas resolvemos colocar o nome de Pk por facilidade de assimilação com o antigo frameowrks... Mas seria um ID do Hibernate ou do JPA por exemplo...

E se vc quizesse, no meio do projeto, criar o método sbrubleCliente()? Ai sim vc teria que criar uma interface para o repositorio de cliente e refatorar seu código para utilizar tal interface, extendendo de HibernateGenericRepository etc.... Porque não criar logo essa interface, extrendendo do lugar correto?
Nós temos um gerador de código para isso... ai a aplicação já vem na estrutura certinha pra isso...



Humm... Se eu tiver apenas um GenericDAO que serve todas as entidades quando são adicionadas novas entidades não preciso mexer no DAO.
Se precisar criar um método especial ( acho que é isso a que se refere) então basta herdade GenericDAO para um CienteDAO com o método especial. Herdar, não reimplementar toda a interface.

Outra opção é vc ter um ClienteRepository que faz o papel de criar os Criteria e enviar para o DAO respectivo.
(Com Criteria generico isto é simples, tlv com Criteria especifico do Hibernate não seja. ) Ou seja, Terei um GenericDAO com os métodos list e find que mostrei acima e um ClienteRepository com os métodos que vc mostrou tipo Cliente sbrubleCliente() ou findClientesQuePediramProduto(Produto p) que são muito especificos
mas que se resumem a criar um Criteria e enviar ao DAO.

This message was edited 2 times. Last update was at 20/09/2007 16:50:06


Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
rodrigoallemand
GUJ Ranger
[Avatar]

Membro desde: 21/02/2005 20:19:47
Mensagens: 972
Localização: Rio de Janeiro, Recreio!!!
Offline

sergiotaborda wrote:
entendi. Mas se o DAO é genérico não deveria os Criteira tb ser ?
Ou seja, a interface deveria ser apenas:



Aquele Criteria não é o do Hibernate. É um objeto que contém a query em forma de grafo que cada dao irá converter. No caso do Hibernate do futuro JPA vc converte para o objeto Criteria deles. Para um DAO JDBC puro vc converte direto para SQL.

Ok, eu sei que da ideia à prática vai um pedaço. No framework que eu uso é usada esta estratégia. Como o DAO é puro JDBC o mapeamento é direto para SQL e funciona bem.
(Entende-se que com um mecanismo assim o Hibernate/JPA tem poucas vantagens)


CriteriaType, como no meu código, é o meu item genérico... no seu código está Ctriteria, que ai sim é a classe do hibernate... E o lance é justamente não ter Cast (esse é o boom do Generics [TypeSafety])...
Com isso o org.hibernate.Criteria (não sei se o pacote é esse) pode ser passado, o java.jpa.Criteria (?!?!?) tambem pode ser usado e o fulano.CriteriaArretadoDeBom tambem pode ser passado...


sergiotaborda wrote:
Humm... Se eu tiver apenas um GenericDAO que serve todas as entidades quando são adicionadas novas entidades não preciso mexer no DAO.
Se precisar criar um método especial ( acho que é isso a que se refere) então basta herdade GenericDAO para um CienteDAO com o método especial. Herdar, não reimplementar toda a interface.

Outra opção é vc ter um ClienteRepository que faz o papel de criar os Criteria e enviar para o DAO respectivo.
(Com Criteria generico isto é simples, tlv com Criteria especifico do Hibernate não seja. ) Ou seja, Terei um GenericDAO com os métodos list e find que mostrei acima e um ClienteRepository com os métodos que vc mostrou tipo Cliente sbrubleCliente() ou findClientesQuePediramProduto(Produto p) que são muito especificos
mas que se resumem a criar um Criteria e enviar ao DAO.


Ok. É uma abordagem genérica de Generics... a ideia é que vc implemente a interface ClienteRepository extendendo do HibernateRepository pra justamente vc ter um repositorio "genericamente especializado" (hehehe), ou seja, vc escreve a classe uma vez só e implementa pra entidade que vc quizer, usando o TypeSafety do Generics...
MAs a sua abordagem tb é valida... mas eu acho que vale gastar 1 min (que é o que vc irá gastar) pra gerar uma interface mais especializada.

This message was edited 1 time. Last update was at 20/09/2007 18:08:07


Rodrigo Allemand

A culpa é minha e eu a coloco em quem eu quizer!. (Homer Simpson)
http://blog.rodrigoallemand.com.br
[WWW] [MSN]
marciobarroso
Virtual Machine Man
[Avatar]

Membro desde: 13/05/2005 23:17:13
Mensagens: 508
Localização: Barueri / SP / BR
Offline

Cara ... no blog da caelum tem um post sobre Daos Genéricos com muitas implementações.

Dá uma olhada lá.

link

This message was edited 1 time. Last update was at 20/09/2007 18:19:40

[Email] [WWW] [MSN]
acdesouza
JavaChild
[Avatar]

Membro desde: 20/08/2007 02:57:52
Mensagens: 110
Localização: Rio de Janeiro
Offline

Tenho uma implementação de DAO Genérico com uma DAOFactory Dinâmica.

O código que usa a DAOFactory e o DAO fica mais ou menos assim:

[],
AC
[WWW]
root_
JavaGuru
[Avatar]

Membro desde: 05/09/2006 15:46:19
Mensagens: 206
Localização: Gurupi - Tocantins
Offline

Nuss.. que bom q esse meu post do tempo em que eu estava ainda crú no hibernate gerou uma discussão boa...

Estou quase com uma classe DAO genérica que na qual utilizo o melhor dentre varios conceitos abordados aqui...
Mais a diante posto o resultado...

Rogério Milhomens de Queiroz
Agile - Consultoria em Tecnologia da Informação!
http://www.agilecti.com.br
Dataview - Inteligência em Tecnologia!
http://www.dataview.com.br
[Email] [WWW] [MSN]
 
Índice dos Fóruns » Java Avançado
Ir para:   
Powered by JForum 2.1.8 © JForum Team