package de.sub.goobi.persistence;
/**
* This file is part of the Goobi Application - a Workflow tool for the support of mass digitization.
*
* Visit the websites for more information.
* - http://digiverso.com
* - http://www.intranda.com
*
* Copyright 2011, intranda GmbH, Göttingen
*
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions
* of the GNU General Public License cover the whole combination. As a special exception, the copyright holders of this library give you permission to
* link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and
* conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this
* library, you may extend this exception to your version of the library, but you are not obliged to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import dubious.sub.goobi.helper.encryption.exceptions.InfrastructureException;
//TODO: Fix for Hibernate-Session-Management, replaced with older version,
// the newer version follows on bottom of this class
/**
* Basic Hibernate helper class, handles SessionFactory, Session and Transaction.
* <p>
* Uses a static initializer for the initial SessionFactory creation and holds Session and Transactions in thread local variables. All exceptions are
* wrapped in an unchecked InfrastructureException.
*
* @author christian@hibernate.org
*/
@SuppressWarnings("deprecation")
public class HibernateUtilOld {
private static Log log = LogFactory.getLog(HibernateUtilOld.class);
private static Configuration configuration;
private static SessionFactory sessionFactory;
private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();
private static final ThreadLocal<Transaction> threadTransaction = new ThreadLocal<Transaction>();
private static final ThreadLocal<Interceptor> threadInterceptor = new ThreadLocal<Interceptor>();
// Create the initial SessionFactory from the default configuration files
static {
try {
configuration = new Configuration();
sessionFactory = configuration.configure().buildSessionFactory();
// We could also let Hibernate bind it to JNDI:
// configuration.configure().buildSessionFactory()
} catch (Throwable ex) {
// We have to catch Throwable, otherwise we will miss
// NoClassDefFoundError and other subclasses of Error
log.error("Building SessionFactory failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}
/**
* Returns the SessionFactory used for this static class.
*
* @return SessionFactory
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* Returns the original Hibernate configuration.
*
* @return Configuration
*/
public static Configuration getConfiguration() {
return configuration;
}
/**
* Rebuild the SessionFactory with the static Configuration.
*
*/
public static void rebuildSessionFactory() throws InfrastructureException {
synchronized (sessionFactory) {
try {
sessionFactory = getConfiguration().buildSessionFactory();
} catch (Exception ex) {
throw new InfrastructureException(ex);
}
}
}
/**
* Rebuild the SessionFactory with the given Hibernate Configuration.
*
* @param cfg
*/
public static void rebuildSessionFactory(Configuration cfg) throws InfrastructureException {
synchronized (sessionFactory) {
try {
sessionFactory = cfg.buildSessionFactory();
configuration = cfg;
} catch (Exception ex) {
throw new InfrastructureException(ex);
}
}
}
/**
* Retrieves the current Session local to the thread.
* <p/>
* If no Session is open, opens a new Session for the running thread.
*
* @return Session
*/
public static Session getSession() throws InfrastructureException {
Session s = threadSession.get();
try {
if (s == null) {
if (getInterceptor() != null) {
log.debug("Using interceptor: " + getInterceptor().getClass());
s = getSessionFactory().openSession();
} else {
s = getSessionFactory().openSession();
}
threadSession.set(s);
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return s;
}
/**
* Closes the Session local to the thread.
*/
public static void closeSession() throws InfrastructureException {
try {
Session s = threadSession.get();
threadSession.set(null);
if (s != null && s.isOpen()) {
s.close();
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
/**
* Start a new database transaction.
*/
public static void beginTransaction() throws InfrastructureException {
Transaction tx = threadTransaction.get();
try {
if (tx == null) {
log.debug("Starting new database transaction in this thread.");
tx = getSession().beginTransaction();
threadTransaction.set(tx);
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
/**
* Commit the database transaction.
*/
public static void commitTransaction() throws InfrastructureException {
Transaction tx = threadTransaction.get();
try {
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
log.debug("Committing database transaction of this thread.");
tx.commit();
}
threadTransaction.set(null);
} catch (HibernateException ex) {
rollbackTransaction();
throw new InfrastructureException(ex);
}
}
/**
* Commit the database transaction.
*/
public static void rollbackTransaction() throws InfrastructureException {
Transaction tx = threadTransaction.get();
try {
threadTransaction.set(null);
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
log.debug("Tyring to rollback database transaction of this thread.");
tx.rollback();
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
} finally {
closeSession();
}
}
/**
* Disconnect and return Session from current Thread.
*
* @return Session the disconnected Session
*/
public static Session disconnectSession() throws InfrastructureException {
Session session = getSession();
try {
threadSession.set(null);
if (session.isConnected() && session.isOpen()) {
session.disconnect();
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return session;
}
/**
* Register a Hibernate interceptor with the current thread.
* <p>
* Every Session opened is opened with this interceptor after registration. Has no effect if the current Session of the thread is already open,
* effective on next close()/getSession().
*/
public static void registerInterceptor(Interceptor interceptor) {
threadInterceptor.set(interceptor);
}
private static Interceptor getInterceptor() {
Interceptor interceptor = threadInterceptor.get();
return interceptor;
}
// nicht sicher ob so korrekt implementiert
public static boolean hasOpenSession() {
Session s = threadSession.get();
if (s == null) {
return false;
}
return true;
}
}