/******************************************************************************* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. *******************************************************************************/ package at.gv.egovernment.moa.id.commons.db; import java.util.Properties; import org.apache.commons.lang3.StringUtils; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.logging.Logger; public final class MOASessionDBUtils { private static SessionFactory sessionFactory; private static ServiceRegistry serviceRegistry; @SuppressWarnings("rawtypes") private static final ThreadLocal THREAD_LOCAL = new ThreadLocal(); private static boolean automaticSessionHandling = false; private static final String[] AUTOMATIC_SESSION_HANDLING_VALUES = new String[] { "jta", "thread" }; private static final String SESSION_HANDLING_KEY = "hibernate.current_session_context_class"; protected MOASessionDBUtils() { } public static void initHibernate(Configuration config, Properties hibernateProperties) { String scm = StringUtils.trimToNull(hibernateProperties.getProperty(SESSION_HANDLING_KEY)); if (scm != null) { automaticSessionHandling = scm.indexOf(AUTOMATIC_SESSION_HANDLING_VALUES[0]) != -1 || scm.indexOf(AUTOMATIC_SESSION_HANDLING_VALUES[1]) != -1; } Logger.debug("Evaluating hibernate property \"" + SESSION_HANDLING_KEY + "\"."); if (automaticSessionHandling) { Logger.info("Hibernate is automatically handling session context management."); } else { Logger.info("Hibernate is NOT automatically handling session context management. Using build-in ThreadLocal session handling."); } try { //Create the SessionFactory Logger.debug("Creating initial MOASession session factory..."); config.configure("hibernate_moasession.cfg.xml"); //serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); serviceRegistry = new StandardServiceRegistryBuilder(). applySettings(config.getProperties()).build(); sessionFactory = config.buildSessionFactory(serviceRegistry); Logger.debug("Initial MOASession session factory successfully created."); } catch (Throwable ex) { Logger.error("Initial MOASession session factory creation failed: " + ex.getMessage()); throw new ExceptionInInitializerError(ex); } } /** * Checks if a session factory is currently available. If necessary a new * session factory is created. * * @return current (or new) session factory * @throws HibernateException * thrown if a hibernate error occurs */ public static Session getCurrentSession() { if (automaticSessionHandling) { return sessionFactory.getCurrentSession(); } Session session = (Session) THREAD_LOCAL.get(); // Open a new Session, if this Thread has none yet if (session == null || !session.isConnected()) { session = getNewSession(); } return session; } @SuppressWarnings("unchecked") public static Session getNewSession() { if (automaticSessionHandling) { Logger.warn("Session is being automatically handled by hibernate. Therefore this session maybe not being newly created. Use HibernateUtil.getCurrentSession() instead."); return sessionFactory.getCurrentSession(); } Session session = (Session) THREAD_LOCAL.get(); if (session != null) { Logger.warn("Previous MOASession session has not been closed; closing session now."); closeSession(); } Logger.debug("Opening new MOASession hibernate session..."); try { session = sessionFactory.openSession(); THREAD_LOCAL.set(session); } catch (HibernateException hex) { Logger.error(hex.getMessage()); } return session; } /** * Closes the current session. * * @throws HibernateException * thrown if session is already closed or a hibernate error * occurs. */ @SuppressWarnings("unchecked") public static void closeSession() { if (automaticSessionHandling) { Logger.warn("Session is being automatically handled by hibernate. Therefore the current session cannot be closed on demand."); return; } Logger.debug("Closing current MOASession hibernate session..."); Session session = (Session) THREAD_LOCAL.get(); THREAD_LOCAL.set(null); if (session != null) { try { session.close(); } catch (HibernateException hex) { Logger.error(hex.getMessage()); } } } public static boolean saveOrUpdate(Object dbo) throws MOADatabaseException { Transaction tx = null; try { Session session = MOASessionDBUtils.getCurrentSession(); synchronized (session) { tx = session.beginTransaction(); session.saveOrUpdate(dbo); tx.commit(); } return true; } catch(HibernateException e) { Logger.warn("Error during MOASession database saveOrUpdate. Rollback.", e); tx.rollback(); throw new MOADatabaseException(e); } } public static boolean delete(Object dbo) { Transaction tx = null; try { Session session = MOASessionDBUtils.getCurrentSession(); synchronized (session) { tx = session.beginTransaction(); session.delete(dbo); tx.commit(); } return true; } catch(HibernateException e) { Logger.warn("Error during MOASession database delete. Rollback.", e); tx.rollback(); return false; } } }