Java tutorial
// // Informa -- RSS Library for Java // Copyright (c) 2002 by Niko Schmuck // // Niko Schmuck // http://sourceforge.net/projects/informa // mailto:niko_schmuck@users.sourceforge.net // // This library is free software. // // You may redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation. // // Version 2.1 of the license should be included with this distribution in // the file LICENSE. If the license is not included with this distribution, // you may find a copy at the FSF web site at 'www.gnu.org' or 'www.fsf.org', // or you may write to the Free Software Foundation, 675 Mass Ave, Cambridge, // MA 02139 USA. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied waranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // $Id: HibernateUtil.java,v 1.5 2006/12/04 23:43:28 italobb Exp $ // package de.nava.informa.utils.manager.hibernate; import de.nava.informa.impl.hibernate.SessionHandler; import de.nava.informa.utils.manager.PersistenceManagerException; import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.Session; import java.util.logging.Level; import java.util.logging.Logger; import sun.misc.Lock; /** * Hibernate session utility. Using it to get sessions you will ensure * that only session is created only once per thread. * * @author Aleksey Gureev (spyromus@noizeramp.com) */ final class HibernateUtil { private static final Logger LOG = Logger.getLogger(HibernateUtil.class.getName()); private static final ThreadLocal<Session> SESSION = new ThreadLocal<Session>(); private static SessionHandler sessionHandler; private static boolean inited; private static Lock lock; static { inited = false; lock = new Lock(); } /** * Hidden constructor of utility class. */ private HibernateUtil() { } /** * Performs initialization. * * @throws HibernateException if problems with Hibernate occur. */ private static synchronized void init() throws HibernateException { // Create the SessionFactory sessionHandler = SessionHandler.getInstance(System.getProperties()); inited = true; } /** * Opens new session or returns currently open session for this thread. * * @return session object. * @throws HibernateException if something with session creation goes wrong. */ public static Session openSession() throws HibernateException { if (!inited) init(); Session s = SESSION.get(); if (s != null) { LOG.log(Level.WARNING, "Openning session more than once from the same thread!", new Exception("Dump")); s.clear(); return s; } else { try { lock.lock(); } catch (InterruptedException e) { throw new RuntimeException("Interrupted waiting for session."); } s = sessionHandler.getSession(); SESSION.set(s); } return s; } /** * Closes previousely opened session. */ public static void closeSession() { Session s = SESSION.get(); SESSION.set(null); if (s != null) { try { s.close(); } catch (HibernateException e) { LOG.log(Level.SEVERE, "Could not close session.", e); // We can do nothing here. // The other session will be opened next time. } lock.unlock(); } else { LOG.log(Level.SEVERE, "Broken sequence of calls. Session is not opened or already closed."); try { throw new NullPointerException(); } catch (NullPointerException e) { } } } /** * Makes a try to lock object. This will save us great number of SQL statements * in several cases. It's not a big problem if locking is not possible. * * @param o object to lock. * @param s session to lock object in. */ public static void lock(Object o, Session s) { try { s.lock(o, LockMode.NONE); } catch (HibernateException e) { // Well, it's possible that object is dirty. } } /** * Saves object into storage. * * @param object object to save. * @throws PersistenceManagerException in case of any problems during saving. */ public static void saveObject(final Object object) throws PersistenceManagerException { // Save object in new session saveObject(object, null); } /** * Saves object into storage. * * @param object object to save. * @throws PersistenceManagerException in case of any problems during saving. */ public static void saveObject(final Object object, Session session) throws PersistenceManagerException { boolean isForeignSession = session != null; try { // Open new session if we are not in the foreign one if (!isForeignSession) { session = openSession(); } session.save(object); // Flush only if it's our own session if (!isForeignSession) { session.flush(); session.connection().commit(); } } catch (Exception e) { // Rollback transaction if we are owners of session if (!isForeignSession) { try { session.connection().rollback(); } catch (Exception e1) { // Error is not recoverable. } } LOG.log(Level.SEVERE, "Couldn't save object.", e); throw new PersistenceManagerException("Couldn't save object.", e); } finally { // Close session if we had opened it if (!isForeignSession) { closeSession(); } } } /** * Updates object in storage. * * @param object object to update. * @throws PersistenceManagerException in case of any problems during updating. */ public static void updateObject(final Object object) throws PersistenceManagerException { updateObject(object, null); } /** * Updates object in storage. * * @param object object to update. * @param session session to use. If NULL then new session is opened. * @throws PersistenceManagerException in case of any problems during updating. */ public static void updateObject(final Object object, Session session) throws PersistenceManagerException { boolean isForeignSession = session != null; try { // Open new session if we are not in the foreign one if (!isForeignSession) { session = openSession(); } session.update(object); // Flush only if it's our own session if (!isForeignSession) { session.flush(); session.connection().commit(); } } catch (Exception e) { // Rollback transaction if we are owners of session if (!isForeignSession) { try { session.connection().rollback(); } catch (Exception e1) { // Error is not recoverable. } } LOG.log(Level.SEVERE, "Couldn't update object.", e); throw new PersistenceManagerException("Couldn't update object.", e); } finally { // Close session if we had opened it if (!isForeignSession) { closeSession(); } } } /** * Deletes object from database using existing session. * * @param object object to delete. * @param session session to use. If NULL then new session is opened. * @throws PersistenceManagerException in case of any problems during deletion. */ public static void deleteObject(final Object object, Session session) throws PersistenceManagerException { boolean isForeignSession = session != null; try { // Open new session if we are not in the foreign one if (!isForeignSession) { session = openSession(); } session.delete(object); // Flush only if it's our own session if (!isForeignSession) { session.flush(); session.connection().commit(); } } catch (Exception e) { // Rollback transaction if we are owners of session if (!isForeignSession) { try { session.connection().rollback(); } catch (Exception e1) { // Error is not recoverable. } } LOG.log(Level.SEVERE, "Couldn't delete object.", e); throw new PersistenceManagerException("Couldn't delete object.", e); } finally { // Close session if we had opened it if (!isForeignSession) { closeSession(); } } } }