Java tutorial
/* * 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; } }