Upload
orangota
View
41
Download
2
Embed Size (px)
Citation preview
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 1/19
Search Search
Sobre Código
Desenvolvimento de Software, palestras, tutoriais e treinamentos
HomeContato
« links for 2006-12-27
links for 2006-12-30 »
Dec 27
DAO Generico – um exemplo a pedidos
Categories:
Dia a Dia
by admin
Bom, no blog da Caelum a um tempo atras fizeram um POST sobre um DAO genérico, meio bizarro …
Bom, eu uso um DAO genérico a algum tempo, mas o meu DAO genérico tm algumas features a mais do que o mostrado no post da caelum …
Neste exemplo eu ja deixo os metodos para fazer um query by example prontinho, usando a API de criteria do Hibernate …
bom, chega de enrolação, vamos a alguns exemplos …
primeiro, crio uma interface para este DAO …
package br.com.techoffice.site.dao;
import java.io.Serializable;import java.util.List;
public interface TOBaseDao<T, PK extends Serializable> { public Class getObjectClass(); public T save(T object); public T load(PK primaryKey); public T get(PK primaryKey); public List listAll(); public List findByExample(final T example); public T findOneByExample(final T example); public List listAll(final int first,final int max); public int listAllPageCount(); public List findByExample(final T example,final int first,final int max); public int findByExamplePageCount(final T example); public void update(T object); public void delete(T object); public void rebind(T object);}
onde o método getObjectClass() deve retornar a classe de trabalho deste DAO, a mesma passada no parâmetro T quando a interface for estendida …
e a implementação desta interface, fica mais ou menos assim:
package br.com.techoffice.site.dao.impl;
import java.io.Serializable;import java.util.List;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.Criteria;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.criterion.Example;import org.hibernate.criterion.MatchMode;
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 2/19
import org.hibernate.criterion.Example.PropertySelector;
import org.hibernate.type.Type;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import br.com.techoffice.site.dao.TOBaseDao;import br.com.techoffice.site.dao.TODaoListener;
@Transactional(propagation = Propagation.REQUIRED, timeout = 20)public abstract class TOBaseHibernateDao extends HibernateDaoSupport implements TOBaseDao<T, PK>, PropertySelector { private static final Log logger = LogFactory.getLog(TOBaseHibernateDao.class); private final Class objectClass;
public TOBaseHibernateDao(final Class objectClass) { this.objectClass = objectClass; }
@SuppressWarnings("unchecked") public Class getObjectClass() { return objectClass; }
public int findByExamplePageCount(final T example) { final List l = findByExample(example); final Integer i = new Integer(l.size()); return i.intValue(); }
public int listAllPageCount() { final List l = listAll(); final Integer i = new Integer(l.size()); return i.intValue(); }
/* * (non-Javadoc) * * @see br.ufrgs.hcpa.template.dao.GetNetBaseDao#findOneByExample(T) */ public T findOneByExample(final T example) { final List res = findByExample(example, 0, 1); if ((res != null) && (res.size() == 1)) { return res.get(0); } else { return null; } }
public T save(final T object) { try { final Session s = getSession(false); s.save(object); s.flush(); return object; } catch (final HibernateException ex) { TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
public void update(final T object) { try { final Session s = getSession(false); s.update(object); s.flush(); } catch (final HibernateException ex) { TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
public void rebind(final T object) { try { getSession(false).refresh(object); } catch (final HibernateException ex) { TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
public void delete(final T object) { try { getSession(false).delete(object); } catch (final HibernateException ex) { TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
@SuppressWarnings("unchecked") public T load(final PK primaryKey) { try { final Session s = getSession(false); final Object o = s.load(objectClass, primaryKey); return (T) o; } catch (final HibernateException ex) {
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 3/19
TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
@SuppressWarnings("unchecked") public T get(final PK primaryKey) { try { final Session s = getSession(false); final Object o = s.load(objectClass, primaryKey); return (T) o; } catch (final HibernateException ex) { TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
@SuppressWarnings("unchecked") public List listAll() { try { final Session s = getSession(false); final Criteria c = s.createCriteria(objectClass); addOrderToCriteria(c); return c.list(); } catch (final HibernateException ex) { TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
@SuppressWarnings("unchecked") public List findByExample(final T example) { try { final Session s = getSession(false); final Criteria c = s.createCriteria(objectClass); c.add(Example.create(example).enableLike(MatchMode.ANYWHERE).ignoreCase().setPropertySelector(this)); addOrderToCriteria(c); addPropertiedToCriteria(c, example); return c.list(); } catch (final HibernateException ex) { TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
protected void addPropertiedToCriteria(final Criteria c, final T example) { }
@SuppressWarnings("unchecked") public List findByExample(final T example, final int first, final int max) { try { final Session s = getSession(false); final Criteria c = s.createCriteria(objectClass); c.add(Example.create(example).enableLike(MatchMode.ANYWHERE).ignoreCase().setPropertySelector(this)); addPropertiedToCriteria(c, example); addOrderToCriteria(c); if (first != 0) { c.setFirstResult(first); } if (max != 0) { c.setMaxResults(max); } return c.list(); } catch (final HibernateException ex) { TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
@SuppressWarnings("unchecked") public List listAll(final int first, final int max) { try { final Session s = getSession(false); final Criteria c = s.createCriteria(objectClass); addOrderToCriteria(c); if (first != 0) { c.setFirstResult(first); } if (max != 0) { c.setMaxResults(max); } return c.list(); } catch (final HibernateException ex) { TOBaseHibernateDao.logger.error(ex); throw convertHibernateAccessException(ex); } }
protected void addOrderToCriteria(Criteria c) { }
public boolean include(Object propertyValue, String propertyName, Type type) { if((propertyValue!=null) && (propertyValue instanceof String)){ return !"".equals(((String)propertyValue).trim()); } return propertyValue!=null; }
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 4/19
}
onde o método addOrderToCriteria, permite que subclasses deste DAO ordenem as consultas …
o método addPropertiedToCriteria permite que subclasses adicionem propriedades não incluidas pelo hibernate nas consultas …
e o método include combinado com o setPropertySelector da classe Example é uma melhoria adicionada a pouco tempo, que faz o mesmo que o addPropertiedToCriteria, mas
de forma automática, ou seja, inclui as propriedades PK e FK também na QBE ……
Bom, depois disto tudo, só falta criar o DAO para alguma entidade persistida pelo Hibernate, como por exemplo uma classe Curriculo …
Criamos a interface do nosso DAO:
package br.com.techoffice.site.dao;
import br.com.techoffice.site.data.Curriculo;
public interface CurriculoDao extends TOBaseDao{}
e logo depois a implementação deste DAO:
package br.com.techoffice.site.dao.impl;
import net.java.dev.springannotation.annotation.Bean;import br.com.techoffice.site.dao.CurriculoDao;import br.com.techoffice.site.data.Curriculo;
@Bean(name="curriculoDao")public class CurriculoDaoImpl extends TOBaseHibernateDao implements CurriculoDao { private static final long serialVersionUID = 1L;
public CurriculoDaoImpl() { super(Curriculo.class); }}
acho que era isto, o que acharam deste DAO genérico?pela minha experiência, ele resolve de maneira estupidamente fácil em torno de 60% dos meus problemas de persistencia, nos outros 40% ai é necessário criar algum outro
metodo de pesquisa especializado para cada situação …
mas acho que é esta a ideia das coisas genéricas, facilitar a maior parte do trabalho e permitir que a menor parte seja feita com um pouquinho de trabalho extra o que vocês
acham?
Tags: Java
Profile
Sign in with Twitter Sign in with Facebook
or
Name
Email Not published
Website
Message: *
Post It
71 Replies
71 Comments0 Tweets
0 Facebook
0 Pingbacks
Last reply was June 22, 2010
1. Alexandre
View December 27, 2006
PERFEITO ESSE DAO!
Urubatan muito bom post. Muito bem explicado!!!
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 5/19
Parabens amigo!!!
Reply
2. Rodrigo Guedes de Souza
View December 27, 2006
Urubatan eu tinha visto este seu DAO num workshop no webdays, ficou muito bom mesmo …..
Reply
3. GécenView December 28, 2006
Parabéns pelo trabalho que vem realizando pela comunidade, há algum tempo acompanho, então resolvi deixar meu recado…
Reply
4. ThiagoView December 28, 2006
Opa Uburatan ta show esse dao genérico, parabéns.
Tenho umas duvidas simples.
esse Propagation.REQUIRED está dizendo que a transação é obrigatória para todos os métodos? aquele mesmo esquema quando declarado via xml?
E a respeito do include ai, você explicou mas eu fiquei viajando, poderia explicar de outra forma ou passar algum link?
Como você está utilizando o HibernateDaoSuport, teria alguma vantagem se utilizasse o método getHibernateTemplate() e/ou utilizar aquele esquema da interfacer
HibernateCallback ?
Uma correção besta é que no método get está utilizando load ou invés de get.
Reply
5. Urubatan
View January 2, 2007
Valeus Gécen
Thiago,
o Propagation.REQUIRED é do spring, e sim, quando ele esta anotando uma classe diz que todos os metodos requerem uma transação …
quanto ao include, o esquema é que o QueryByExample do Hibernate não inclui campos de relacionamento e PKs, aquele include é chamado quando eu chamo
[java]
Example.create(example).enableLike(MatchMode.ANYWHERE).ignoreCase().setPropertySelector(this)
[/java]
ou seja, é o callback do property selector do hibernate apenas …
e quanto a HibernateTemplate X convertHibernateAccessException(ex);
uso a segunda opção por que acho mais bonito só, mas não vejo nenhuma razão concreta para usar uma ou a outra abordagem …
Reply
6. Thiago
View January 3, 2007
Olá Urubatan, entendi agora, vlw.
Só mais uma duvida.
E a respeito do objectClass que é passado como construtor das classes concretas, ele é realmente preciso já que estamos passando o tipo via generics? eu vi no blog da
caleum um artificio que não precisaria dessa classe, conforme no link abaixo:
http://blog.caelum.com.br/2006/10/29/brincando-com-generics-o-bizarregenericdao/
o que você acha dessa solução?
Reply
7. TetsuoView January 3, 2007
Eu tb escrevi um pouco sobre a classe que é passada no construtor (ou melhor, sobre a ‘mágica’ necessária pra eliminá-lo):
http://javapub.blogspot.com/2006/12/generics-reflection-hierarquias-de.html
No fim, eu achei melhor manter essa passagem por parâmetro do que me aventurar nessa zona obscura
Reply
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 6/19
8. Diogo Cabral
View January 8, 2007
Oi,
O dao ficou muito bom. Gostaria de saber se você não acha mais interessante algo como “return listAll().size()” no lugar de instanciar um Integer nos métodos de pagecount?
Abraços
Reply
9. UrubatanView January 8, 2007
realmente seria melhor …
não lembro por que esta implementado desta forma, deve ter ficado assim em alguma das metamorfoses sofridas por este DAO durante o tempo de vida dele e eu não
prestei atenção :S
Vaoeu a dica
Reply
10. Juan Damasceno
View January 29, 2007
Legal, muito boa implementação, existiria alguma forma de injetar o objectClass pelo Spring?
Reply
11. Diego Pires Plentz
View February 12, 2007
Urubatan, por curiosidade, porque você chama o flush() após o save() e update()?
Reply
12. Urubatan
View February 12, 2007
sim, é possivel injetar o objectClass pelo spring …
e diego, eu realmente não lembro o por que do flush, acho que no projeto em que eu fiz isto, estava dando algum bug de batch update e eu tentei resolver assim antes de
desabilitar o batch update do hibernate …
Reply
13. ronildojunior
View February 14, 2007
Muito bom o DAO
So uma duvida… nao seria melhor ter uma classe de negocio e colocar a anotacao dizendo que é requirido uma trasacao nela
por exemplo:
@Transactional(propagation = Propagation.REQUIRED, timeout = 20)
public class ContaCorrente(){
public retirar(){
ContaDAO conta = factory.getContaDAO();
UsuarioDAO usuario = factory.getUsuarioDAO();
…
}}
assim todos os DAOs estariam dentro de uma mesma transacao… eu faco uma implementacao assim
Reply
14. Urubatan
View February 14, 2007
A vantagem desta abordagem é que a configuração mais externa é a que vale.
por exemplo, estou dizendo que os metodos do DAO requerem uma transação, isto não quer dizer uma transação nova …
por tanto, se no business, o metodo necessitar de uma transação, sera criada uma transação para aquele metodo, e todas as chamadas de dao de dentro daquele metodo
utilizarão a mesma transação, por tanto, todas as chamadas estarão dentro da mesma transação …
assim a transação sera maior, e ainda assim atomica.
mas caso o metodo do business não precisar de uma transação, serão criadas pequenas transações para cada chamada a um metodo de um DAO.
ou seja, fica valendo a maior transação
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 7/19
Reply
15. Mário Dantas
View February 16, 2007
Olá Urubatan, primeiramente parabéns pelo trabalho, tenho uma dúvida sobre transação.
Por exemplo em uma transação em que eu tenha q inserir dados de uma nova venda e dados de itens dessa venda, essa implementação do Dao genérico contempla esse
tipo de situação ou tenho que fazer isso por fora.
inicio da transacao
…
daoVenda.salvar(venda);
daoItens.salvar(itens);
…fim da transacao
algo onde a transação deveria ser mais ou menos assim, um exemplo tosco só para ter um idéia.
Mais uma vez parabéns pela iniciativa.
Reply
16. Urubatan
View February 16, 2007
Mário, da uma olhada no meu comentário anterior que explica exatamente isto …
Reply
17. Mário Dantas
View February 16, 2007
Beleza, pensei que com objetos de dao’s diferentes ele fazia diferentes transacoes.
Valeu.
Reply
18. ronildo
View April 9, 2007
Ola
Copiando o que vc escreveu:
A vantagem desta abordagem é que a configuração mais externa é a que vale.
por exemplo, estou dizendo que os metodos do DAO requerem uma transação, isto não quer dizer uma transação nova
Gostaria de saber como vc fez para trabalhar com essa abordagem, o seu artigo explica detalhes de como funciona o DAO generic, que por sinal é muito bom, mas nao
explica como fazer o controle de transação. Vc tem algum material explicando como fazer ?
Obrigado.
Reply
19. Urubatan
View April 13, 2007
Ronildo, desculpe a demora na resposta, não tinha visto a pergunta …
o controle de transações funciona exatamente como em um session bean com CMT, ou seja, vale a transação de maior escopo …demarcação para a classe vale para todos os métodos
demarcação no método sobre escreve a da classe
e se tem todas as opções de propagação de transações que existem nos EJBs.mais informações sobre isto na documentação dos EJBs ou na documentação do spring
Reply
20. Lucas Húngaro
View April 17, 2007
Urubatan, gostei da sua implementação do TOBaseHibernateDao e passei a utilizar algo bem semelhante como base para meus Daos.
Utilizo também uma factory para os Daos, mas estou com um problema com as transações:
Erro: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
Pesquisei bastante sobre isso, mas não encontrei uma solução. Consigo fazer com o funcione se chamar getSession(true), isto é, permitindo que uma transação seja
criada nesse momento, o que não é recomendado, pelo que li.
Como você configura seu applicationContext para usar essa implementação?
Outra dúvida, relativa à pergunta do Mário Dantas: como eu consigo começar e finalizar uma transação “por fora” dos Daos, já que eles não expõe os métodos relativos
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 8/19
à session?
Reply
21. Thiago
View April 17, 2007
Dê uma conferida aqui Lucas.
http://pastebin.co.uk/13149
Reply
22. Lucas Húngaro
View April 17, 2007
Valeu Thiago! Havia encontrado algo semelhante aqui uns minutos antes de você postar e me deparei com outro erro. Usei o que você postou (achei melhor do que o
que eu havia encontrado, pois especifica mais níveis de isolamento).
Porém, agora estou com outro erro…
Faço um listAll() numa classe Cliente. Essa classe possui uma Collection com lazy loading. Para buscar os clientes dá tudo certo. Porém, quando tento iterar pela coleção
de pedidos:
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:
com.lecom.tecnologia.model.Cliente.pedidos, no session or session was closed
at
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163)
at com.lecom.tecnologia.main.Tester.test(Tester.java:29)
at com.lecom.tecnologia.main.Main.main(Main.java:17)
Pelo jeito a sessão está sendo “perdida”. O logger me retorna algumas coisas relacionadas a isso (após selecionar os clientes com sucesso):
DEBUG [main] (TransactionAspectSupport.java:305) - Completing transaction for [com.lecom.tecnologia.dao.IGenericDao.listAll]
DEBUG [main] (AbstractPlatformTransactionManager.java:819) - Triggering beforeCommit synchronization
DEBUG [main] (AbstractPlatformTransactionManager.java:832) - Triggering beforeCompletion synchronization
DEBUG [main] (TransactionSynchronizationManager.java:190) - Removed value
[org.springframework.orm.hibernate3.SessionHolder@3b4b1e] for key [org.hibernate.impl.SessionFactoryImpl@c0a9f9] from thread
[main]
DEBUG [main] (AbstractPlatformTransactionManager.java:845) - Triggering afterCommit synchronization
DEBUG [main] (AbstractPlatformTransactionManager.java:861) - Triggering afterCompletion synchronization
DEBUG [main] (SessionFactoryUtils.java:781) - Closing Hibernate Session
DEBUG [main] (TransactionSynchronizationManager.java:272) - Clearing transaction synchronization
Alguma idéia?
Reply
23. Thiago
View April 17, 2007
Ai nesse caso, você tem que carregar a coleção de pedidos antecipadamente, pois quando você tenta acessa-la a sessão já foi fechada por isso da o lazy.
Vai lá na documentação do hibernate e procura sobre fetch, você pode setar no seu mapeamento como default para sempre carregar a coleção, ou no metodo que
estiver realizando a query, via criteria ou hql, especificar se deve carregar ou não.
Reply
24. Lucas Húngaro
View April 17, 2007
Pois é, nas buscas que eu fiz encontrei isso mesmo. Ele fecha a sessão após cada transação, então ao tentar pegar a lista de pedidos vai dar erro pois já é outra sessão…
A minha dúvida é: por esse motivo perco o benefício de desempenho que ganho com o lazy loading? Não há outro jeito a não ser fazer a query novamente utilizando left
join fetch?
Reply
25. Urubatan
View April 17, 2007
ùma solução para isto é se você estiver utilizando Hibernate sem o spring (o que parece por causa da factory que você mencionou) mudar na configuracão do hibernate
para managed sessions, assim você cria e destroi as sessions.
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 9/19
caso esteja utilizando o spring utilize algo parecido com isto:
[java]
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
if(sessionHolder==null){
TransactionSynchronizationManager.bindResource(getSessionFactory(),new SessionHolder(getSessionFactory().openSession());}[/java]
não se esqueça que fazendo isto você é o responsável por fechar a sessão também …
Reply
26. Urubatan
View April 17, 2007
PS.: eu achei muito legal outro visitante do blog responder uma duvida em um comentário
Muito obrigado Thiago.
Reply
27. Lucas Húngaro
View April 17, 2007
Muito legal a inciativa do Thiago mesmo.
Urubatan, estou usando o Spring sim. É uma prática ruim usar uma DaoFactory com Spring?
Não tenho o código agora, está no trabalho, mas fiz mais ou menos o seguinte:
Uma interface genérica, semelhante a sua TOBaseDao.
Uma classe abstrata com a implementação dessa interface para o hibernate, como a classe TOBaseHibernateDao.Uma interface genérica para a DaoFactory, com métodos como: public IClienteDao getClienteDao;
Uma interface e implementação para cada Dao, onde posso colocar métodos específicos.
A implementação da factory possui os atributos (as interfaces dos Daos) que são injetadas via método set pelo Spring.
Nas classes que consomem os Daos, tenho apenas a interface da factory como atributo e a implementação é injetada pelo Spring.
Obrigado pelo retorno, vou tentar isso no trabalho amanhã (trabalho da faculdade hoje =/ ).
Sobre a minha segunda pergunta no primeiro post, alguma orientação? A mais óbvia que vejo seria colocar dentro de um Dao chamadas a outros, fazendo tudo na
transação do primeiro, mas acho que isso não é muito bom…
Reply
28. Lucas Húngaro
View April 18, 2007
Como não quero ter que controlar a sessão, fiz o seguinte: antes de acessar a coleção de pedidos, uso o método clienteDao.rebind(cliente). Agora ele usa uma transação
para buscar os clientes e depois uma transação para buscar cada lista de pedidos. Funciona, mas achei bem feio…
De acordo com o que pesquisei, o padrão OpenSessionInView resolve isso, está correto?
Reply
29. UrubatanView April 18, 2007
esta solução do rebind funciona também
mas prende o teu código a api do Hibernate se isto não estiver sendo feito dentro de um DAO.
se bem que não é exatamente um problema prender o código a API do Hibernate
PS.: o OpenSessionInView também resolve isto …
Reply
30. Lucas Húngaro
View April 18, 2007
Urubatan, como você costuma contornar essa situação? Ou você não utiliza lazy loading?
Reply
31. Thiago
View April 18, 2007
Opa, vlw pessoal.
Eu não custumo utilizar muito lazy loading, pelo menos no projeto no qual estou envolvido.
Como utilizo ajax, via DWR, quando realizo as consultas geralmente trago tudo que eu quero, como o sistema não lida com grande volume de dados creio que não tem
problemas, fora que realizo paginações para trazer uma quantidade limitada de dados.
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 10/19
Reply
32. Urubatan
View April 18, 2007
Lucas, eu uso lazy bastante e como a maior parte das apps é web, o OpenSessionInView ja resolve o meu problema …quando trabalho com ajax procuro não utilizar as mesmas entidades (hoje estou fazendo isto e estou transformando em HashMaps os valores transferidos via ajax.
e quando o OpenSessionInView não resolve, como esta semana que tive que implementar um wizard com a sessão aberta durante todo o wizard, eu copiei o
OpenSessionInView filter do Spring, e fiz com que quando eu estivesse no wizard, ele armazenasse a session na HttpSession e usando um código parecido com:
[java]SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
if(sessionHolder==null){
TransactionSynchronizationManager.bindResource(getSessionFactory(),new SessionHolder(getSessionFactory().openSession());
}
[/java]
ele enquanto ainda no wizard, recuperasse a sessão do HttpSession e utilizasse a mesma durante todo o wizard
mas como sempre, a solução mais apropriada, depende de cada situação
Reply
33. Lucas Húngaro
View April 18, 2007
Legal… por enquanto estou apenas testando o Spring com Hibernate, então estou escrevendo uma aplicação console mesmo. Esse “esquema” do SessionHolder
funcionou bem, apenas adicionei o “unbinding” antes de finalizar a aplicação:
TransactionSynchronizationManager.unbindResource(this.sessionFactory);
SessionFactoryUtils.releaseSession(session, this.sessionFactory);
Estou fazendo uma aplicação também em .NET com NHibernate e lá costumo colocar a session no HttpSession também… funciona =D
Alguma opinião sobre a minha implementação com factory? Estive pensando: seria bom eu configurar os beans dos Daos como lazy-init? Acho que seria uma boa, já quena factory eu tenho a injeção de todos os Daos, mas não vou utilizar todos sempre.
Reply
34. Urubatan
View April 18, 2007
bom, sobre a factory …
containers IoC foram criados para que ninguem mais utilizasse factories …
por tanto, ou tu utiliza o spring ou a tua dao factory, não as duas coisas junto …
mas esta é só a minha opinião
Reply
35. Lucas Húngaro
View April 18, 2007
Sim, faz sentido… na verdade essa factory não tá criando nada, ela apenas retorna os daos que são injetados, então ela acaba perdendo a semântica de criadora,passando a ser apenas um objeto agregador, ou seja, acaba não sendo uma factory de verdade.
Vi muita gente usando Spring e Castle Windsor (container IoC pra .NET) com essa “factory”, então acabei fazendo da mesma forma. Vou procurar saber mais sobre
isso.
Obrigado pela ajuda!
Reply
36. Gessé
View July 10, 2007
Olá Urubatan,
Primeio gostaria de parabenizar pelo DAO genérico que vc construi. Desenvolvi um dao bem parecido com esse aí, só que o único problema aí é que tenho que criar
uma classe dao concreta para todas as minhas classes persistíveis.
Há alguma forma de isso não ser necessário?
Reply
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 11/19
37. Urubatan
View July 10, 2007
é só alterar ele para passar o objectClass como parametro para o método que precisar dele
Reply
38. Marcos Peron
View August 6, 2007
Olá,
Muito bom seu artigo!!
So fiquei com uma dúvida:
E se eu quisesse que uma classe CurriculoDireito que estende Curriculo tivesse também um DAO que extendesse o DAO de Curriculo, como proceder?
public interface CurriculoDAO extends TOBaseDao{
public List getCurriculosByName();
}
Estou batendo a cabeça aqui mas não acho solução.
public interface CurriculoDireitoDAO extends CurriculoDAO {
// este deve ser implicito
// public List getCurriculosByName();
public List getCurriculoEstruturaDireito();
}
é uma sugestão meio tosca, mas o que eu gostaria era de poder Herdar os metodos das interfaces dos DAOs..
Postei uma dúvida sobre isso no GUJ, e me direcionaram para seu blog
http://www.guj.com.br/posts/list/66036.java
se você tiver alguma idéia, seria muito grato.
vlw
Abraços e parabéns!
Reply
39. Urubatan
View August 6, 2007
não entendi a dúvida …este DAO genérico não atrabalha em nada a utilização de herança …
Reply
40. Maria sanchesView September 14, 2007
para dar um exemplo de um blog
Reply
41. HewertonView October 2, 2007
Urubatan, poderia me explicar como funciona exatamente este método…public List findByExample(final T example, final int first, final int max)
Reply
42. alexandreView October 20, 2007
Urubatan…
esse “T” quer dizer o que mesmo ?que é um tipo indefinido ?
Reply
43. Urubatan
View October 20, 2007
alexandre, isto é a sintaxe de generics do Java 5
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 12/19
Reply
44. Gilberto santos
View January 18, 2008
ola urubatan.sobre sua primeira classe TOBaseDao
certez
Reply
45. Gilberto santosView January 18, 2008
ola urubatan.
sobre sua primeira classe TOBaseDaobom, como ela implementa classe Generic sem receber o parametro
TOBaseDao
essa e minha duvida !
abs.
Reply
46. Alexandre
View April 13, 2008
Algum exemplo sem utilizar spring? com struts 2
Reply
47. FabioView May 18, 2008
Achei bem legal essa classe, muito útil também.
Sobre os métodos para contar regitros, fico meio preocupado, pois caso a tabela seja muito grande, todos os registros serão carregados?Não teria como fazer uma verificação só da qtde, como faríamos com o SQL (select count(*) from tabela)?
Valeu
Reply
48. Rafael AntunesView September 26, 2008
Meio tarde mas se ajudar ainda:Fabio em uma entidade se vc mapear ela com@LazyCollection(LazyCollectionOption.EXTRA)
O hibernate fica mais esperto no carregamento lazy, se vc der somente um size(), ele ira dar um count, tambem fica mais esperto quanto ao contains, verifica pelo bancoem vez de carregar a lista e verificar em memoria.
Reply
49. RaphelView December 10, 2008
Olá Urubatan,
Eu utilizo hibernate(jpa) com um dao genérico e funciona perfeitamente, exceto quando tento inserir uma entidade que herda outra entindade abstrata.
Eu uso apenas um dao para todas as entidades filhas e por padrão o dao recebe o .class da entidade pai. Isto funciona perfeitamente para consultas polimórficas, porémao inserir as classes filhas apenas os atributos herdados são persistidos.
É possível fazer uma inserção “polimórfica” através do dao da entidade pai?
Reply
Urubatanreplied:
View December 11, 2008
é possível sim, provavelmente você esqueceu de colocar o @Entity nas classes filhas
Reply
Raphaelreplied:
View January 27, 2009
Valeu!!!
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 13/19
Eu já havia corrigido o problema e realmente era uma anotação da classe.
Na anotação @Column de um atributo eu coloquei insertable=false, por pensar que funcionava de outra forma.
Depois que arrumei funcionou corretamente.
Reply
50. Francisco RafaelView January 23, 2009
Desculpe minha falta de informação, mas não entendi como utilizar esta implementação, para cada classe minha cliente, produto vou ter que implementar um DAO?gostaria de fazer um classe generica onde passar o objeto e lá dentro tratar tudo generico pelo que vi este exemplo faz isso, mas não entendi como utilizar esta interfaceserá que alguém poderia dar um exemplo de como instanciar um objeto utilizando esta implemenação?
Reply
51. Raphael
View January 27, 2009
Bom dia Francisco,
No meu caso eu tenho um DAO genérico que contém apenas os métodos que são comuns a todas as entidades, o mesmo é abstrato.
Os demais daos herdam o dao genérico.
Porém por questões de manutenabilidade e também por utilizar o spring, o struts 2 e o hibernate (obs: acredito que nenhum dos frameworks obriga o uso de interface),
todas as minhas daos possuem uma interface e nas Actions (Struts 2) eu delcaro as minhas instâncias com a Interface e o Spring se encarrega de criar a intânciacorrespondente e injetá-lo na Action.
import scfc.model.dao.ChamadoDAO;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.Preparable;
public class ManterOrdemServico extends ActionSupport implements Preparable, SessionAware{
//interfaceprivate ChamadoDAO chamadoDao;
//…
}
Desse modo, caso eu queira mudar a implementação do meu dao generico basta criar uma nova classe que implemente a interface da minha entidade e que herde a novaimplementação da classe genérica. E no xml de configuração do spring, basta mudar a classe para a nova.
Isso facilita mto, pois esse tipo de alteração torna-se transparente para o restante do sistema.
public interface GenericDAO {
void save(T entity);
void update(T entity);
void remove(T entity);
T find(ID id);
List findAll();
T getReference(ID id);
}
@Transactional
public abstract class GenericImplDAO implements GenericDAO{
private Class persistentClass;
@PersistenceContextprivate EntityManager em;
@SuppressWarnings(“unchecked”)public GenericImplDAO(){this.persistentClass = (Class)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public void setEm(EntityManager em) {this.em = em;
}
protected EntityManager getEm() {
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 14/19
return em;
}
public Class getPersistentClass() {return persistentClass;
}
@Overridepublic void save(T entity) {
em.persist(entity);}
@Override
public void update(T entity){em.merge(entity);
}
@Overridepublic void remove(T entity) {
em.remove(entity);}
@Override
public T find(ID id) {return em.find(getPersistentClass(), id);}
@Overridepublic List findAll() {
return findByCriteria();}
@SuppressWarnings(“unchecked”)
protected List findByCriteria(Criterion… criterion) {
Session session = (Session) em.getDelegate();
Criteria crit = session.createCriteria(getPersistentClass());
for (Criterion c : criterion) {
crit.add(c);}
return crit.list();
}
@SuppressWarnings(“unchecked”)protected List findByCriteria(Order o, Criterion… criterion) {
Session session = (Session) em.getDelegate();
Criteria crit = session.createCriteria(getPersistentClass());
for (Criterion c : criterion) {crit.add(c);
}
crit.addOrder(o);
return crit.list();}
@Overridepublic T getReference(ID id) {
return getEm().getReference(getPersistentClass(), id);
}
}
public interface ServicoDAO extends GenericDAO {
List findAllForContrato(Categoria cat);
}
public class ServicoImplDAO extends GenericImplDAO implements ServicoDAO {
@Override
public List findAllForContrato(Categoria categoria) {
Conjunction c = Restrictions.conjunction();
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 15/19
c.add(Expression.eq(“contrato”, true));
c.add(Expression.eq(“categoria”, categoria));
return findByCriteria(c);
}
}
Espero ter ajudado.
Reply
Leonardoreplied:View April 16, 2009
Raphael, você poderia dar mais detalhes da sua integração entre Struts2 + Spring + Hibernate(JPA) ao qual se referiu no seu post? Poderia postar o
applicationContext?orbigado,
Leonardo
Reply
Raphaelreplied:
View April 17, 2009
Exemplo de um applicationContext.xml.
<!– Alternativa caso queira configurar a conexão com o banco direto da aplicação
–>
Na documentação do Spring mostra outras alternativas para algumas configurações.
No site do Struts 2 (versão 0) tem um exemplo de intregralção entre eles, há também um exemplo de integração no site da revista java magazine.
Mas se sugirem dúvidas posta ai.
Reply
Raphaelreplied:View April 17, 2009
Ops…
deu algum erro na hora de postar.segue novamente o applicationContext.xml.
<!– Alternativa caso queira configurar a conexão com o banco direto da aplicação
–>
Reply
Raphaelreplied:
View April 17, 2009
Troquei o símbolo de comentário do xml por //, vamos ver se agora vai.
// Usa o JNDI configurado no Container
// Alternativa caso queira configurar a conexão com o banco direto da aplicação
//////
////
//
// Atentar-se para a propriedade database, ela corresponder ao seu banco.// Veja na documentação do spring qual o valor que você deve colocar.
//
Reply
52. Francisco Rafael
View January 27, 2009
Muito obrigado ajudou sim, e esclareceu bastante dúvidas…vlw cara.
Reply
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 16/19
53. Anderson
View March 31, 2009
Olá urubatan, esse tutorial foi feito em dezembro de 2006. Até hoje tenho procurado alguma coisa mas recente sobre isso e não tenho encontrado. O que estouquerendo é exatamente as configurações do hibernate no meu applicationContext mas só enconto artigos antigos. Tem algo mais recente que possa me indicar?
Grato!
Reply
54. Gessé
View April 1, 2009
Anderson,
Quanto as configurações do hibernate no applicationContext, você pode criar um datasource no context.xml e pegar a conexão via jndi no applicationContext
Reply
55. AndersonView April 1, 2009
Olá Gessé,
Algumas coisas ainda são meio obscuras para mim, mas nada que não possa ser resolvido. Já estou quase conseguindo, de qualquer forma agradeço pela força.
Reply
56. Gessé
View April 1, 2009
Ok Anderson…
Qualquer coisa é só perguntar…
Reply
57. RaphaelView April 17, 2009
deu erro denovo.
<!– Alternativa caso queira configurar a conexão com o banco direto da aplicação
–>
Reply
58. Ginhu
View April 22, 2009
Cara como fica isso no spring ? O genericDao tem que ter alguma configuracao especifica ?
valeu
Reply
59. AndersonView April 22, 2009
O genericDao não, mas o hibernate sim.
No momento ainda não consegui configurar no spring, mas estou utilizando uma classe utilitaria temporaria e espero jogar isso pro spring em breve.
Reply
60. IBMView February 18, 2010
Lembrando que esse exemplo foi criado a partir de: http://www.ibm.com/developerworks/java/library/j-genericdao.html
É sempre bom citar a fonte de onde se copia a informação.
Reply
Urubatanreplied:
View February 21, 2010
Na verdade o código é semelhante mas o meu não foi baseado neste não, a idéia eu tive partindo do exemplo postado no blog da caelum como cito no início dopost, só li este link que você enviou depois de já estar utilizando o meu Dao genérico por algum tempo.
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 17/19
Mas obrigado pelo link.
Reply
61. ernani
View February 23, 2010
cmo ficaria a integracao desse dao generico com o spring, no caso o spring +hibernate.. ?
Reply
62. felipe.ar
View April 15, 2010
Poxa, achei que não estã tão completo…Foi o primeiro resultado da pesquisa do google…
Reply
63. Bruno DildaView June 21, 2010
Estava procurando por um DAO genérico e até agora foi o melhor que eu achei.
Porém estou com um problema de implementação.Quando tento rodar aparece o erro:
“java.lang.IllegalArgumentException: No SessionFactory specified
at org.springframework.util.Assert.notNull(Assert.java:112)at org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:281)
at org.springframework.orm.hibernate3.SessionFactoryUtils.getSession(SessionFactoryUtils.java:200)at org.springframework.orm.hibernate3.support.HibernateDaoSupport.getSession(HibernateDaoSupport.java:165)
at mignard.dao.impl.TOBaseHibernateDao.listAll(TOBaseHibernateDao.java:136)”
Saberia me dizer o erro ou o que tenho que fazer para funcionar?
Reply
64. Bruno DildaView June 22, 2010
Tirei a parte do spring e mudei o get session e esta funcionando =)
Reply
Search Search
Powered by Webbynode
Recent Posts
Nomenclatura de entidades (classes, métodos, variáveis) no código – o que fazer, o que não fazer, regras a seguir
Video e Exemplos da minha palestra do Just Jva 2013Por que qualidade de código é importante, e por que a falta dele pode acabar com um projeto
Just Java 2013 – Vamos falar de Java EE e Rails trabalhando juntos!Curso online (Hangout) de BDD com cucumber – melhorando a comunicação e automatizando os testes de software
Recent Comments
admin on Comentário no código é para os fracosJoao on Em fim, um concorrente para o AdSense (é, parece que perdi a vez)
Maristane Thomazi on Brasão da familia Jardimmarista jardim on Brasão da familia Jardimmarista jardim on Brasão da familia Jardim
Archives
June 2013
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 18/19
May 2013April 2013March 2013
January 2013September 2012
August 2012July 2012
May 2012February 2012January 2012
December 2011November 2011
October 2011September 2011
August 2011May 2011March 2011
February 2011January 2011
November 2010September 2010
August 2010July 2010June 2010
May 2010April 2010
February 2010January 2010
December 2009November 2009October 2009
September 2009August 2009
July 2009June 2009
May 2009April 2009March 2009
February 2009January 2009
December 2008November 2008
October 2008September 2008
July 2008June 2008May 2008
April 2008March 2008
February 2008January 2008
December 2007November 2007October 2007
September 2007August 2007
July 2007June 2007
May 2007April 2007March 2007
February 2007January 2007
December 2006November 2006
October 2006September 2006August 2006
July 2006June 2006
May 2006April 2006
March 2006February 2006January 2006
December 2005November 2005
October 2005
18/09/13 DAO Generico – um exemplo a pedidos » Sobre Código
sobrecodigo.com/dao-generico-um-exemplo-a-pedidos/ 19/19
September 2005August 2005July 2005
June 2005May 2005
April 2005March 2005
November 2004August 2004
July 2004June 2004
Categories
ArtigosCursos
Dia a DiaflexHistórico
JavaMobile
Node.JSrails
RubyScalaTrabalho
Uncategorized
Meta
Log in
Entries RSSComments RSS
WordPress.org
Copyright
© 2013 Sobre Código.
Return to top
Powered by WordPress and the Graphene Theme.