Hibernate - Erro na inicializacao e Dois Bancos (Tomcat 5)
8 respostas
black_fire
E ai pessoal,
:?: Estou tendo um erro na inicialização do Hibernate, porém não sei se isso está interferindo no seu funcionamento, pois eu executei uma query e ela funcionou sem problemas.
1 - se vc tirar este name do session-factory -> <session-factory name=“java:comp/env/hibernate/SessionFactory”> continua o erro?
2 - nunca fiz o Hibernate se conectar em dois bancos como vc está fazendo, mas para existem um método openSession(Connection connection) em SessionFactory que vc pode usar para o Hibernate usar a conexao que vc passou.
black_fire
Isso mesmo, retirei o java:comp/env/hibernate/SessionFactory e o erro não ocorreu mais.
:?: Só uma coisa, para que serve este name?
“ricardolecheta”:
2 - nunca fiz o Hibernate se conectar em dois bancos como vc está fazendo, mas para existem um método openSession(Connection connection) em SessionFactory que vc pode usar para o Hibernate usar a conexao que vc passou.
Vou precisar trabalhar constantemente com dois bancos de dados ou talvez até três… Estes acessos não serão esporádicos já que possuo sistemas distintos que trabalham com SQLServer, Oracle e Postgresql.
:idea: Se alguém por ai já teve alguma experiência semelhate. Qualquer dica vai ajudar muito…
Um abraço galera…
ricardolecheta
é para obter a SessionFactory a partir de um nome JNDI...
vc pode criar 2 Configuration... e para cada uma vc cria uma SessionFactory para obter suas Sessions...
o Configuration possui um método configure() que por default procura o hibernate.cfg.xml, mas vc pode passar outro assim:
Configuration cfg = new Configuration(); Configuration cfg2 = new Configuration(); cfg.configure("/hibernate.cfg.xml"); cfg2.configure("/hibernate2.cfg.xml"); sessionFactory = cfg.buildSessionFactory(); sessionFactory2 = cfg2.buildSessionFactory();
entao vc terá duas SessionFactory... :D
black_fire
Valeu acho que isso resolve o meu problema, deixo como hibernate.cfg.xml a conexão que eu mais uso e passo por parâmetros as outras.
importjava.io.IOException;importjavax.servlet.Filter;importjavax.servlet.FilterChain;importjavax.servlet.FilterConfig;importjavax.servlet.ServletException;importjavax.servlet.ServletRequest;importjavax.servlet.ServletResponse;importnet.sf.hibernate.SessionFactory;importnet.sf.hibernate.Session;importnet.sf.hibernate.Transaction;importnet.sf.hibernate.HibernateException;importnet.sf.hibernate.cfg.Configuration;publicclassSessionManagerimplementsFilter{protectedstaticThreadLocalhibernateHolder=newThreadLocal();protectedstaticThreadLocaltxHolder=newThreadLocal();protectedstaticSessionFactoryfactory;publicvoidinit(FilterConfigfilterConfig)throwsServletException{// Initialize hibernatetry{factory=newConfiguration().configure().buildSessionFactory();}catch(HibernateExceptionex){thrownewServletException(ex);}}publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{if(hibernateHolder.get()!=null)thrownewIllegalStateException("A session is already associated with this thread! "+"Someone must have called getSession() outside of the context "+"of a servlet request.");try{chain.doFilter(request,response);}finally{Sessionsess=(Session)hibernateHolder.get();Transactiontx=(Transaction)txHolder.get();if(sess!=null){hibernateHolder.set(null);try{if(tx!=null){tx.commit();}sess.close();}catch(HibernateExceptionex){thrownewServletException(ex);}}}}publicstaticSessiongetSession()throwsHibernateException{Sessionsess=(Session)hibernateHolder.get();Transactiontx=(Transaction)txHolder.get();if(sess==null){sess=factory.openSession();txHolder.set(sess.beginTransaction());hibernateHolder.set(sess);}else{if(tx==null){thrownewIllegalStateException("Transaction was allready rolled back");}}returnsess;}publicstaticvoidrollback()throwsHibernateException{Transactiontx=(Transaction)txHolder.get();if(tx==null){thrownewIllegalStateException("Transaction was allready rolled back");}tx.rollback();txHolder.set(null);}publicvoiddestroy(){try{factory.close();}catch(HibernateExceptionex){thrownewRuntimeException(ex);}}}
ricardolecheta
fazer isso é questão de gosto, a sacada é que vc deve ter uma SessionFactory apenas, neste exemplo o autor usou este Filter para controlar isso.
outro jeito seria simplesmente implementar o pattern ThreadLocal numa classe separada, assim: http://www.hibernate.org/42.html
no exemplo foi feito o lookup para recuperar a SessionFactory… vc pode alterar isto se quiser, mas lembre-se de criar apenas uma nesta classe…
Ai é só usar esta classe HibernateSession.currentSession() para obter a Session de onde vc precisar…
ricardolecheta
a outra coisa, bacana este tutorial que vc passou
black_fire
Fiz uma alteração no filter.
Não tenho certeza se é uma alteração correta. ou se terei que fazer uma classe para cada um dos bancos de dados que estarei utilizando
Vejam:
Estarei pondo apenas partes do código acima:
Primeiro eu crio uma sessionFactory para cada banco de dados
Depois no getSession eu informo a session de qual banco de dados de que estou solicitando:
.../** * Resgata a session atual: * * @param dataBase - 0: Postgresql, 1: Oracle */publicstaticSessiongetSession(intdataBase)throwsHibernateException{Sessionsess=(Session)hibernateHolder.get();Transactiontx=(Transaction)txHolder.get();if(sess==null){switch(dataBase){case0:sess=factoryPG.openSession();case1:sess=factoryORCL.openSession();}txHolder.set(sess.beginTransaction());hibernateHolder.set(sess);}else{if(tx==null){thrownewIllegalStateException("Transaction was allready rolled back");}}returnsess;}...
ricardolecheta
o melhor é deixar um filtro apenas mesmo, me parece que sua alteração está certa sim.
O legal de fazer o filtro é que vc pode usar o pattern “Open Session in View”, isto é util quando vc usa o lazy-loading do Hibernate… pq se vc fechar a Session e mandar para a view, sempre que vc for acessar um objeto ainda nao carregado vai dar pau !
ai com o filter, a Session do Hibernate ainda vai estar aberta na view , entao vc pode usar o lazy-loading mais facil…