podd.dataaccess.hibernate.AbstractHibernateDAOImpl.java Source code

Java tutorial

Introduction

Here is the source code for podd.dataaccess.hibernate.AbstractHibernateDAOImpl.java

Source

/*
 * 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();
    }

}