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

Java tutorial

Introduction

Here is the source code for com.nec.crud.hibernate.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.hibernate;

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.StatelessSession;
import org.hibernate.jdbc.Work;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate4.SessionFactoryUtils;
import org.springframework.util.Assert;

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

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

    private static SessionFactory sessionFactory;

    public HibernateSessionManager(SessionFactory sf) {
        sessionFactory = sf;
    }

    /**
     * Retrieves the Hibernate SessionFactory that will be used to create new
     * sessions.
     * 
     * @return Returns the SessionFactory from which Hibernate sessions are
     *         created.
     */
    public static SessionFactory getSessionFactory() {
        Assert.notNull(sessionFactory, "No SessionFactory specified");

        return sessionFactory;
    }

    /**
     * Gets the active session for this request, creating it as necessary. When
     * the session is first created, a transaction is started.
     * 
     * @return the request's session
     */
    public static Session getSession() {
        // ??????
        Session session = getSessionFactory().openSession();

        // No Hibernate Session bound to thread
        Assert.notNull(session, "No Hibernate Session bound to thread");

        // 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
        if (!isConnected(session) || session.isDirty()) {
            // ?
            closeSession(session);

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

    /**
     * Gets the active stateless Session for this request
     * 
     * @return
     */
    public static StatelessSession getStatelessSession() {
        return getSessionFactory().openStatelessSession();
    }

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

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

    /**
      * Web?????????
      * 
      * @return ?
      * @throws SQLException
      *             ?
      */
    public static Connection getConnection() throws SQLException {
        return SessionFactoryUtils.getDataSource(getSessionFactory()).getConnection();
    }

    /**
     * Ask the Hibernate session to execute the unit of work
     * 
     * @param session
     * @return
     */
    private static boolean isConnected(Session session) {
        try {
            session.doWork(new PingConnectionWork());
        } catch (Exception ex) {
            logger.warn(ex.getMessage(), ex);

            // FALSE if connection is closed
            return false;
        }
        return true;
    }

    /**
     * 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) {
                logger.warn(ex.getMessage(), ex);

                // Attempt to rollback to avoid 'tx aborted' error
                if (!connection.isClosed()) {
                    connection.rollback();
                }
                throw ex;
            } finally {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

}