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 info.aduna.collections.iterators.CloseableIterator; import info.aduna.collections.iterators.IteratorWrapper; import java.lang.reflect.ParameterizedType; import java.util.Collection; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; import org.hibernate.LockOptions; import org.hibernate.NonUniqueObjectException; import org.hibernate.ObjectNotFoundException; import org.hibernate.Session; import org.springframework.orm.hibernate3.HibernateSystemException; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import podd.dataaccess.Idempotent; import podd.exception.DataAccessException; import podd.model.entity.PoddObject; /** * @author Yuan-Fang Li * @version $Id$ */ @SuppressWarnings({ "unchecked" }) public abstract class AbstractHibernateDAOImpl<T> extends HibernateDaoSupport implements HibernateDAO<T> { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractHibernateDAOImpl.class); @Override @Idempotent @Deprecated public T load(Long id) throws DataAccessException { try { Class<T> actualClassParameter = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; List list = getHibernateTemplate().find( "SELECT e FROM " + actualClassParameter.getName() + " e WHERE e.id=?", new Object[] { id }); if (list.size() > 0) return (T) list.get(0); else return null; } catch (ObjectNotFoundException e) { return null; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new DataAccessException("Error loading entity. " + e.getMessage(), e); } } protected T doLoad(String pid, Class<T> clazz) throws DataAccessException { try { T result; List list = getHibernateTemplate().find("SELECT p FROM " + clazz.getName() + " p WHERE pid=?", new Object[] { pid }); if (list.isEmpty()) { result = null; } else { result = (T) list.get(0); } return result; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new DataAccessException("Error loading entity. " + e.getMessage(), e); } } @Override public T load(String id) throws DataAccessException { throw new UnsupportedOperationException("Cannot retrieve entity from hibernate using string PIDs"); } @Override public CloseableIterator<T> loadByLocalName(String id) throws DataAccessException { throw new UnsupportedOperationException("Cannot retrieve entity from hibernate using string IDs"); } @Override @Idempotent public void save(T object) throws DataAccessException { getHibernateTemplate().save(object); } @Override public void update(T object) throws DataAccessException { try { getHibernateTemplate().update(object); } catch (NonUniqueObjectException e) { reattach(object); getHibernateTemplate().merge(object); } catch (HibernateSystemException e) { reattach(object); getHibernateTemplate().merge(object); } } @Override public void saveOrUpdate(T object) throws DataAccessException { try { getHibernateTemplate().saveOrUpdate(object); } catch (NonUniqueObjectException e) { reattach(object); getHibernateTemplate().merge(object); } catch (HibernateSystemException e) { reattach(object); getHibernateTemplate().merge(object); } } @Override @Idempotent public T delete(T object) throws DataAccessException { getHibernateTemplate().delete(object); return object; } @Override public T merge(T object) throws DataAccessException { getHibernateTemplate().merge(object); return object; } @Override @Idempotent public void refresh(T object) throws DataAccessException { getHibernateTemplate().refresh(object); } @Override public void purgeCache(String pid) { } @SuppressWarnings({ "unchecked" }) @Override public CloseableIterator<T> getAll() throws DataAccessException { try { Class<T> actualClassParameter = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; List list = getHibernateTemplate().find("SELECT c FROM " + actualClassParameter.getName() + " c"); return new IteratorWrapper(list.iterator()); } catch (RuntimeException e) { throw new DataAccessException("Error getting all entities. " + e.getMessage(), e); } catch (Exception e) { throw new DataAccessException("Error getting all entities. " + e.getMessage(), e); } } @Override public void reattach(T entity) { if (entity != null) { Session session = getSession(); try { if (PoddObject.class.isAssignableFrom(entity.getClass())) { PoddObject po = (PoddObject) entity; Long id = po.getId(); if (id != null) { try { session.buildLockRequest(LockOptions.NONE).lock(entity); } catch (NonUniqueObjectException e) { LOGGER.info("Merging entity instead of locking"); session.merge(entity); } catch (HibernateException e) { // Catch the following error // org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions LOGGER.info("Merging entity instead of locking"); session.merge(entity); } catch (HibernateSystemException e) { LOGGER.info("Merging entity instead of locking"); session.merge(entity); } } } } catch (HibernateException e) { LOGGER.warn("Found exception", e); } finally { releaseSession(session); } } } /** * Build where in list for a given list of ids * @param ids * @return */ public static String buildWhereInList(Collection<?> ids) { StringBuilder sb = new StringBuilder(); boolean isFirst = true; for (Object id : ids) { if (id != null) { if (isFirst) { isFirst = false; } else { sb.append(","); } if (id instanceof String) sb.append("'"); sb.append(id.toString()); if (id instanceof String) sb.append("'"); } } return sb.toString(); } }