package gov.pr.celepar.tabeliao.database; /* Este programa � licenciado de acordo com a LPG-AP (LICEN�A P�BLICA GERAL PARA PROGRAMAS DE COMPUTADOR DA ADMINISTRA��O P�BLICA), vers�o 1.1 ou qualquer vers�o posterior. A LPG-AP deve acompanhar todas PUBLICA��ES, DISTRIBUI��ES e REPRODU��ES deste Programa. Caso uma c�pia da LPG-AP n�o esteja dispon�vel junto com este Programa, voc� pode contatar o LICENCIANTE ou ent�o acessar diretamente: http://www.celepar.pr.gov.br/licenca/LPG-AP.pdf Para poder USAR, PUBLICAR, DISTRIBUIR, REPRODUZIR ou ALTERAR este Programa � preciso estar de acordo com os termos da LPG-AP */ import org.apache.log4j.Logger; import org.hibernate.FlushMode; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; /** * Le arquivo de configuracao do Hibernate gerando o SessionFactory * e o Configuration. Cria singleton da Session para haver somente * uma sessao em todo o sistema. * Fornece metodos static para recuperar a sessao. * * @author Grupo Framework - Componentes * @version 2.0, 18/01/2005 * @since 1.0 */ public class HibernateUtil { private static Logger logger = Logger.getLogger(HibernateUtil.class); private static SessionFactory sessionFactory; private static final Configuration configuration; private static final ThreadLocal<Session> session = new ThreadLocal<Session>(); private static final ThreadLocal<Transaction> transaction = new ThreadLocal<Transaction>(); private static final ThreadLocal<Integer> countSession = new ThreadLocal<Integer>(); private static final ThreadLocal<Integer> count = new ThreadLocal<Integer>(); private static final ThreadLocal<Boolean> rollback = new ThreadLocal<Boolean>(); static { try { configuration = new Configuration(); sessionFactory = configuration.configure("hibernate-tabeliao.cfg.xml").buildSessionFactory(); } catch (Exception ex) { throw new RuntimeException("[HibernateUtil] Problema de configura��o: " + ex.getMessage(), ex); } } /** * Retorna sessao do Hibernate. Se nao houver sessao, * cria uma nova. * * @return Session Hibernate session * @throws Exception */ public static Session currentSession() throws Exception { if (session.get() == null || !session.get().isOpen()) { session.set(sessionFactory.openSession()); countSession.set(1); } else { countSession.set(countSession.get() + 1); } logger.debug("******************************************************************************************"); logger.debug("*** CurrentSession: " + countSession.get()); logger.debug("******************************************************************************************"); session.get().setFlushMode(FlushMode.COMMIT); return session.get(); } /** * Fecha a sessao do Hibernate. * * @return true se a sessao foi fechada e false caso contr�rio - false indica que esta dentro de uma transacao. * @throws Exception */ public static boolean closeSession() throws Exception { if (transaction.get() != null) { logger.debug("******************************************************************************************"); logger.debug("*** CloseSession com transa��o aberta."); logger.debug("******************************************************************************************"); return false; } if(countSession.get() != null){ logger.debug("******************************************************************************************"); logger.debug("*** CloseSession: " + countSession.get()); logger.debug("******************************************************************************************"); countSession.set(countSession.get() - 1); if(countSession.get() <= 0) { if (session.get() != null) { logger.debug("******************************************************************************************"); logger.debug("*** CloseSession: Fechando a sessao."); logger.debug("******************************************************************************************"); if (session.get().isOpen() && count.get() == null) session.get().flush(); if (session.get().isConnected()) session.get().disconnect(); session.get().close(); } } else { return false; } session.set(null); countSession.set(null); } return true; } /** * Inicia uma transacao se for necessario. Caso ja exista uma, somente a mantem. * Retorna a sessao que esta nesta transacao. * * @throws Exception Problemas ao obter conexao ou iniciar transacao. * */ public static void currentTransaction() throws Exception { try { currentSession(); } catch (Exception e) { throw new Exception ("Erro ao obter sess�o do Hibernate: " + e.getMessage(), e); } /* se j� houver uma transa��o, somente incrementa nosso contador de transac�es. */ if (transaction.get() != null) { count.set(count.get() + 1); } else { transaction.set(session.get().beginTransaction()); count.set(1); rollback.set(false); } logger.debug("******************************************************************************************"); logger.debug("*** CurrentTransaction: " + count.get()); logger.debug("******************************************************************************************"); } /** * Somente tem efeito se a session tiver sido obtida atraves do metodo * getManagedSession. Neste caso, executa um commit na transa��o associada * caso o total de chamadas de getManagedSession tenha sido igual ao total * de commits e caso nao tenha sido chamado nenhum rollback. Caso algum * rollback tenha sido chamado, executa roolback e lanca Exception. * @throws Exception * */ public static void commitTransaction() throws Exception { if (transaction.get() == null) throw new Exception ("N�o existe transa��o associada a esta sess�o!"); if (count.get() != null) { logger.debug("******************************************************************************************"); logger.debug("*** CommitTransaction: " + count.get()); logger.debug("******************************************************************************************"); count.set(count.get() -1); /* caso n�o tenha sido executado um commit para cada begin, n�o executa commit */ if (count.get() > 0) return; if (rollback.get()) { logger.debug("******************************************************************************************"); logger.debug("*** CommitTransaction: Fazendo o rollback"); logger.debug("******************************************************************************************"); transaction.get().rollback(); count.set(null); transaction.set(null); closeSession(); throw new Exception ("Voc� esperava um \"COMMIT\", mas no lugar um \"ROLLBACK\" foi executado. " + "Verifique a execu��o do seu c�digo. Provavelmente alguma transa��o aninhada executou um \"ROLLBACK\"" + "mas n�o foi lancada excess�o para a classe que a chamou tratar e executar \"ROLLBACK\" tamb�m. Lembre-se:" + "utilizar a mesma transa��o."); } logger.debug("******************************************************************************************"); logger.debug("*** CommitTransaction: Fazendo o commit"); logger.debug("******************************************************************************************"); transaction.get().commit(); logger.debug("******************************************************************************************"); logger.debug("*** CommitTransaction: Limpando a transacao e sessao"); logger.debug("******************************************************************************************"); countSession.set(1); count.set(null); transaction.set(null); closeSession(); } else { throw new Exception ("N�o existe transa��o associada a esta sess�o!"); } } /** * Somente tem efeito se a session tiver sido obtida atraves do metodo * getManagedSession. Neste caso, executa um rollback na transacao associada * caso o total de chamadas de getManagedSession tenha sido igual ao total * de commit/rollbacks. * @throws Exception * */ public static void rollbackTransaction() throws Exception { if (transaction.get() == null) { if (rollback.get()) { rollback.set(false); throw new Exception ("\"ROLLBACK\" j� executado por um commit."); } throw new Exception ("N�o existe transa��o associada a esta sess�o!"); } logger.debug("******************************************************************************************"); logger.debug("*** RollbackTransaction: " + count.get()); logger.debug("******************************************************************************************"); if (count.get() != null) { count.set(count.get() -1); /* ops! foi chamado o rollback no meio da transa��o. Devemos nos certificar de que * n�o haver�o commits! */ if (count.get() > 0) { rollback.set(true); return; } logger.debug("******************************************************************************************"); logger.debug("*** RollbackTransaction: Fazendo o rollback"); logger.debug("******************************************************************************************"); transaction.get().rollback(); logger.debug("******************************************************************************************"); logger.debug("*** CommitTransaction: Limpando a transacao e sessao"); logger.debug("******************************************************************************************"); transaction.set(null); rollback.set(false); countSession.set(1); closeSession(); count.set(null); } else { throw new Exception ("N�o existe transa��o associada a esta sess�o!"); } } /** * Fecha a sessao do Hibernate e todas as suas conexoes. * @throws Exception */ public static void shutdown() throws Exception { closeSession(); session.set(null); transaction.set(null); count.set(null); sessionFactory.close(); configuration.setInterceptor(null); } /** * Retorna o objeto Configuration usado * @return Configuration */ public static Configuration getConfiguration() { return configuration; } /** * Retorna a SessionFactory atual * @return SessionFactory */ public static SessionFactory getSessionFactory() { return sessionFactory; } /** * Configura um novo sessionFactory. Pode ser usado para * alterar o arquivo de configuracao do Hibernate. * @param sessionFactory * @throws Exception */ public static void setSessionFactory(SessionFactory sessionFactory) throws Exception { closeSession(); HibernateUtil.sessionFactory = sessionFactory; } }