Java tutorial
/* * Copyright (c) 2009 - 2010. School of Information Technology and Electrical * Engineering, The University of Queensland. This software is being developed * for the "Phenomics Ontoogy Driven Data Management Project (PODD)" project. * PODD is a National e-Research Architecture Taskforce (NeAT) project * co-funded by ANDS and ARCS. * * PODD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PODD is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PODD. If not, see <http://www.gnu.org/licenses/>. */ package podd.dataaccess.hibernate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; import org.hibernate.SQLQuery; import org.hibernate.Session; import podd.exception.DataAccessException; import podd.util.db.HibernateSessionFactory; import podd.util.fedora.PIDGenerator; /** * @author Yuan-Fang Li * @version $Id$ */ public class HibernateFedoraPIDGenerator implements PIDGenerator { private final static Logger LOGGER = LoggerFactory.getLogger(HibernateFedoraPIDGenerator.class); private static final boolean _INFO = LOGGER.isInfoEnabled(); private String pidTableName; private HibernateSessionFactory factory; public HibernateFedoraPIDGenerator(HibernateSessionFactory factory, String pidTableName) { this.factory = factory; this.pidTableName = pidTableName; } @Override // FIXME: TODO YF: This method executed concurrently will sometimes return stale values! public synchronized String getNextPID(String namespace) throws DataAccessException { long start = System.currentTimeMillis(); try { Session session = factory.currentSession(); session.beginTransaction(); try { SQLQuery sqlQuery = createSelectIDSQLQuery(namespace, session); Integer currentPid = (Integer) sqlQuery.uniqueResult(); if (null == currentPid) { currentPid = 0; sqlQuery = createInsertSQLQuery(namespace, session); } else { currentPid++; sqlQuery = createUpdateIDSQLQuery(namespace, session, currentPid); } sqlQuery.executeUpdate(); session.getTransaction().commit(); return namespace + ":" + currentPid.toString(); } catch (Exception e) { session.getTransaction().rollback(); throw new DataAccessException(e); } finally { session.flush(); factory.closeSession(); } } finally { if (_INFO) { long end = System.currentTimeMillis(); LOGGER.info("getNextPID timing=" + (end - start)); } } } public String removeNamespace(String namespace) throws DataAccessException { Session session = factory.currentSession(); try { session.beginTransaction(); SQLQuery selectQuery = createSelectIDSQLQuery(namespace, session); Integer currentPid = (Integer) selectQuery.uniqueResult(); if (null != currentPid) { SQLQuery deleteQuery = createDeleteSQLQuery(namespace, session); deleteQuery.executeUpdate(); } session.getTransaction().commit(); return null == currentPid ? null : namespace + ":" + currentPid; } catch (HibernateException e) { session.getTransaction().rollback(); throw new DataAccessException(e); } finally { factory.closeSession(); } } private SQLQuery createInsertSQLQuery(String namespace, Session session) { final String sqlQueryString = "insert into " + pidTableName + " (namespace, highestID) values ('" + namespace + "', 1)"; return session.createSQLQuery(sqlQueryString); } private SQLQuery createUpdateIDSQLQuery(String namespace, Session session, Integer newPid) { final String sqlQueryString = "update " + pidTableName + " set highestID=" + newPid + " where namespace='" + namespace + "'"; return session.createSQLQuery(sqlQueryString); } private SQLQuery createSelectIDSQLQuery(String namespace, Session session) { String sqlQueryString = "select highestID FROM " + pidTableName + " where namespace='" + namespace + "'"; return session.createSQLQuery(sqlQueryString); } private SQLQuery createDeleteSQLQuery(String namespace, Session session) { String deleteQueryString = "delete from " + pidTableName + " where namespace='" + namespace + "'"; return session.createSQLQuery(deleteQueryString); } }