/*
* Copyright (c) 2005-2011 Grameen Foundation USA
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* See also http://www.apache.org/licenses/LICENSE-2.0.html for an
* explanation of the license and how it is applied.
*/
package org.mifos.framework.hibernate.helper;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.Interceptor;
import org.mifos.framework.exceptions.ConnectionNotFoundException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;
import java.sql.Connection;
import java.util.Properties;
@SuppressWarnings("PMD")
public class HibernateUtil implements FactoryBean<HibernateUtil> {
private SessionFactory sessionFactory;
private static final ThreadLocal<Object> interceptorTL = new ThreadLocal<Object>();
private static final ThreadLocal<Session> sessionTL = new ThreadLocal<Session>();
private final InterceptorFactory interceptorFactory;
public HibernateUtil(InterceptorFactory interceptorFactory, SessionFactory sessionFactory) {
this.interceptorFactory = interceptorFactory;
this.sessionFactory = sessionFactory;
}
public void shutdown() {
try {
sessionFactory.close();
sessionTL.remove();
interceptorTL.remove();
} catch (HibernateException e) {
e.printStackTrace(System.out);
}
sessionFactory = null;
}
public Properties getHibernateProperties() {
return ((AnnotationSessionFactoryBean) sessionFactory).getHibernateProperties();
}
/**
* Return the hibernate session factory
*/
public SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* Return the current hibernate session for this thread. If this thread
* doesn't have one, create a new one.
*/
public Session getSessionTL() {
try {
getOrCreateSession();
} catch (HibernateException he) {
throw new ConnectionNotFoundException(he);
}
return sessionTL.get();
}
public Object getInterceptor() {
return interceptorTL.get();
}
/**
* Begin a transaction and store it in a thread-local variable, or return
* the currently open transaction if there is one. The result is that the
* transaction will remain open until a call to HibernateUtil
* or rollbackTransaction(). Calling this method instead of just
* creating a hibernate Transaction via the session is probably not a good
* idea (see an example of the latter at
* TestObjectPersistence#update(Session,
* org.mifos.framework.business.PersistentObject)
*/
public Transaction startTransaction() {
Transaction transaction = getSessionTL().getTransaction();
if (!transaction.isActive()) {
transaction.begin();
}
return transaction;
}
public void closeSession() {
Session session = sessionTL.get();
if (session != null && session.isOpen()) {
session.close();
}
sessionTL.set(null);
}
public void flushSession() {
sessionTL.get().flush();
}
public void flushAndCloseSession() {
Session session = sessionTL.get();
if (session != null && session.isOpen()) {
session.flush();
session.close();
}
sessionTL.set(null);
}
public void flushAndClearSession() {
Session session = getSessionTL();
if (session.isOpen()) {
session.flush();
session.clear();
}
}
private Session getOrCreateSession() throws HibernateException {
if (sessionTL.get() == null) {
interceptorTL.set(interceptorFactory.create());
Session session = sessionFactory.openSession((Interceptor) interceptorTL.get());
sessionTL.set(session);
}
return sessionTL.get();
}
public void commitTransaction() {
if (getSessionTL().getTransaction().isActive()) {
getSessionTL().getTransaction().commit();
}
}
public void rollbackTransaction() {
if (getSessionTL().getTransaction().isActive()) {
getSessionTL().getTransaction().rollback();
}
}
@Override
public HibernateUtil getObject() throws Exception {
return this;
}
@Override
public Class<?> getObjectType() {
return HibernateUtil.class;
}
@Override
public boolean isSingleton() {
return true;
}
public void clearSession() {
getSessionTL().clear();
}
public Connection getConnection() {
return getSessionTL().connection();
}
}