com.nec.crud.hibernate4.HibernateSessionManager.java Source code

Java tutorial

Introduction

Here is the source code for com.nec.crud.hibernate4.HibernateSessionManager.java

Source

/*
 * Copyright(C) 2014
 * NEC Corporation All rights reserved.
 * 
 * No permission to use, copy, modify and distribute this software
 * and its documentation for any purpose is granted.
 * This software is provided under applicable license agreement only.
 */
package com.nec.crud.hibernate4;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.jdbc.Work;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate4.SessionFactoryUtils;

import com.nec.crud.exception.JDBCConnectionNotFoundException;

/**
 * ??
 * 
 * @author sondn
 *
 */
public final class HibernateSessionManager {

    private static final Logger LOGGER = LoggerFactory.getLogger(HibernateSessionManager.class);

    /**
     * ???
     */
    private static final ThreadLocal<Session> SESSIONS = new ThreadLocal<Session>();

    /**
     * Hibernate?SessionFactory???
     */
    private static SessionFactory sessionFactory;

    /**
     * SessionFactory?? 
     * 
     * @param sf
     */
    public HibernateSessionManager(SessionFactory sf) {
        sessionFactory = sf;
    }

    /**
     * ??????
     * 
     * @return Session
     * @throws SQLException
     */
    public static Session getSession() {
        // Gets the active session for this request, creating it as necessary. When
        // the session is first created, a transaction is started.
        Session session = SESSIONS.get();
        if (session == null) {
            // ??????
            session = getSessionFactory().openSession();
            SESSIONS.set(session);
        } else {
            if (!isConnected(session) || session.isDirty()) {
                // ?
                disconnectAll();

                // ??????
                session = getSession();
            }
        }

        return session;
    }

    /**
     * ?
     * 
     * this is VERY IMPORTANT so that the transaction is commited
     * and the session finalized.
     */
    public static void disconnectAll() {
        final Session session = SESSIONS.get();
        if (session != null && session.isOpen()) {
            session.clear();

            // Perform actual closing of the Hibernate Session, catching and
            // logging any cleanup exceptions thrown.
            SessionFactoryUtils.closeSession(session);
        }
        SESSIONS.remove();
        SESSIONS.set(null);
    }

    /**
     * Get the session factory which created this session
     * 
     * @return The session factory
     */
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    /**
     * Attempts to establish a connection with the data source that this
     * DataSource object represents
     * 
     * @return the JDBC connection in use by the Session
     */
    public static Connection getConnection() {
        try {
            return SessionFactoryUtils.getDataSource(getSessionFactory()).getConnection();
        } catch (SQLException ex) {
            throw new JDBCConnectionNotFoundException(
                    "????????", ex);
        }
    }

    /**
     * Ask the Hibernate session to execute the unit of work
     * 
     * @author sondn
     *
     */
    private static class PingConnectionWork implements Work {

        @Override
        public void execute(Connection connection) throws SQLException {
            CallableStatement statement = null;
            ResultSet resultSet = null;

            try {
                statement = connection.prepareCall("SELECT 1");
                resultSet = statement.executeQuery();
            } catch (Exception ex) {
                if (!connection.isClosed()) {
                    // Attempt to rollback to avoid 'tx aborted' error
                    connection.rollback();
                }
                throw ex;
            } finally {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    /**
     * Ask the Hibernate session to execute the unit of work
     * 
     * @param session
     * @return
     */
    private static boolean isConnected(Session session) {
        try {
            // We're having some difficult to diagnose connection issues at the moment.
            // To experiment lets test the connection when opened, if it fails do a rollback
            session.doWork(new PingConnectionWork());
        } catch (Exception ex) {
            LOGGER.warn(ex.getMessage(), ex);

            // Connection test failed
            return false;
        }
        return true;
    }
}