ubic.gemma.persistence.service.AbstractDao.java Source code

Java tutorial

Introduction

Here is the source code for ubic.gemma.persistence.service.AbstractDao.java

Source

/*
 * The Gemma project.
 *
 * Copyright (c) 2006-2011 University of British Columbia
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package ubic.gemma.persistence.service;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.FlushMode;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;
import ubic.gemma.model.common.Identifiable;
import ubic.gemma.persistence.service.genome.taxon.TaxonServiceImpl;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * AbstractDao can find the generic type at runtime and simplify the code implementation of the BaseDao interface
 *
 * @author Anton, Nicolas
 */
@Transactional
public abstract class AbstractDao<T extends Identifiable> extends HibernateDaoSupport implements BaseDao<T> {

    protected static final Log log = LogFactory.getLog(TaxonServiceImpl.class);

    private final Class<T> elementClass;

    protected AbstractDao(Class<T> elementClass, SessionFactory sessionFactory) {
        super.setSessionFactory(sessionFactory);
        this.elementClass = elementClass;
    }

    @Override
    public Collection<T> create(Collection<T> entities) {
        int i = 0;
        for (T t : entities) {
            this.create(t);
            if (++i % 100 == 0)
                this.getSessionFactory().getCurrentSession().flush();
        }
        return entities;
    }

    @Override
    public T create(T entity) {
        Serializable id = this.getSessionFactory().getCurrentSession().save(entity);
        assert entity.getId() != null : "No ID received for " + entity;
        assert id.equals(entity.getId());
        return entity;
    }

    @Override
    @Transactional(readOnly = true)
    public Collection<T> load(Collection<Long> ids) {
        //noinspection unchecked
        return this.getSessionFactory().getCurrentSession().createQuery( //language=none // Prevents unresolvable missing value warnings.
                "from " + elementClass.getSimpleName() + " e where e.id in (:ids)").setParameterList("ids", ids)
                .list();
    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional(readOnly = true)
    public T load(Long id) {
        // Don't use 'load' because if the object doesn't exist you can get an invalid proxy.
        //noinspection unchecked
        return id == null ? null : (T) this.getSessionFactory().getCurrentSession().get(elementClass, id);
    }

    @Override
    @Transactional(readOnly = true)
    public Collection<T> loadAll() {
        //noinspection unchecked
        return this.getSessionFactory().getCurrentSession().createCriteria(elementClass).list();
    }

    @Override
    public Integer countAll() {
        return ((Long) this.getSessionFactory().getCurrentSession().createQuery( //language=none // Prevents unresolvable missing value warnings.
                "select count(*) from " + elementClass.getSimpleName()).uniqueResult()).intValue();
    }

    @Override
    public void remove(Collection<T> entities) {
        for (T e : entities) {
            this.remove(e);
        }
    }

    @Override
    public void remove(Long id) {
        if (id == null)
            throw new IllegalArgumentException("Id cannot be null");
        this.remove(this.load(id));
    }

    @Override
    public void remove(T entity) {
        if (entity == null)
            throw new IllegalArgumentException("Entity cannot be null");
        this.getSessionFactory().getCurrentSession().delete(entity);
    }

    @Override
    @Transactional
    public void update(Collection<T> entities) {
        for (T entity : entities) {
            this.update(entity);
        }
    }

    @Override
    @Transactional
    public void update(T entity) {
        if (entity == null)
            throw new IllegalArgumentException("Entity cannot be null");
        this.getSessionFactory().getCurrentSession().update(entity);
    }

    @Override
    @Transactional(readOnly = true)
    public T find(T entity) {
        if (entity == null)
            throw new IllegalArgumentException("Entity cannot be null");
        return this.load(entity.getId());
    }

    @Override
    @Transactional
    public T findOrCreate(T entity) {
        if (entity == null)
            throw new IllegalArgumentException("Entity cannot be null");
        T found = this.find(entity);
        return found == null ? this.create(entity) : found;
    }

    /**
     * Does a like-match case insensitive search on given property and its value.
     *
     * @param  propertyName  the name of property to be matched.
     * @param  propertyValue the value to look for.
     * @return               an entity whose property first like-matched the given value.
     */
    @SuppressWarnings("unchecked")
    protected T findOneByStringProperty(String propertyName, String propertyValue) {
        Criteria criteria = this.getSessionFactory().getCurrentSession().createCriteria(this.elementClass);
        criteria.add(Restrictions.ilike(propertyName, propertyValue));
        criteria.setMaxResults(1);
        //noinspection unchecked
        return (T) criteria.uniqueResult();
    }

    /**
     * Does a like-match case insensitive search on given property and its value.
     *
     * @param  propertyName  the name of property to be matched.
     * @param  propertyValue the value to look for.
     * @return               a list of entities whose properties like-matched the given value.
     */
    @SuppressWarnings("SameParameterValue") // Better for general use
    protected List<T> findByStringProperty(String propertyName, String propertyValue) {
        Criteria criteria = this.getSessionFactory().getCurrentSession().createCriteria(this.elementClass);
        criteria.add(Restrictions.ilike(propertyName, propertyValue));
        //noinspection unchecked
        return criteria.list();
    }

    /**
     * Lists all entities whose given property matches the given value.
     *
     * @param  propertyName  the name of property to be matched.
     * @param  propertyValue the value to look for.
     * @return               a list of entities whose properties matched the given value.
     */
    @SuppressWarnings("unchecked")
    protected T findOneByProperty(String propertyName, Object propertyValue) {

        /*
         * Disable flush to avoid NonNullability constraint failures, etc. prematurely when running this during object
         * creation. This effectively makes this method read-only even in a read-write context. (the same setup might be
         * needed for other methods)
         */
        FlushMode fm = this.getSessionFactory().getCurrentSession().getFlushMode();
        this.getSessionFactory().getCurrentSession().setFlushMode(FlushMode.MANUAL);
        Criteria criteria = this.getSessionFactory().getCurrentSession().createCriteria(this.elementClass);
        criteria.add(Restrictions.eq(propertyName, propertyValue));
        criteria.setMaxResults(1);

        //noinspection unchecked
        T result = (T) criteria.uniqueResult();
        this.getSessionFactory().getCurrentSession().setFlushMode(fm);
        return result;
    }

    /**
     * Does a search on given property and its value.
     *
     * @param  propertyName  the name of property to be matched.
     * @param  propertyValue the value to look for.
     * @return               an entity whose property first matched the given value.
     */
    protected List<T> findByProperty(String propertyName, Object propertyValue) {
        Criteria criteria = this.getSessionFactory().getCurrentSession().createCriteria(this.elementClass);
        criteria.add(Restrictions.eq(propertyName, propertyValue));
        //noinspection unchecked
        return criteria.list();
    }

}