br.com.arsmachina.dao.hibernate.ReadableDAOImpl.java Source code

Java tutorial

Introduction

Here is the source code for br.com.arsmachina.dao.hibernate.ReadableDAOImpl.java

Source

// Copyright 2007-2008 Thiago H. de Paula Figueiredo
//
// 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 br.com.arsmachina.dao.hibernate;

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

import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import br.com.arsmachina.dao.ReadableDAO;
import br.com.arsmachina.dao.SortCriterion;

/**
 * {@link ReadableDAO} implementation using Hibernate. All methods use {@link #getSession()} to get
 * {@link Session}.
 * 
 * @author Thiago H. de Paula Figueiredo
 * @param <T> the entity class related to this DAO.
 * @param <K> the type of the field that represents the entity class' primary key.
 */
public abstract class ReadableDAOImpl<T, K extends Serializable> extends BaseHibernateDAO<T, K>
        implements ReadableDAO<T, K> {

    /**
     * A {@link SortCriterion} array with no elements.
     */
    final public static SortCriterion[] EMPTY_SORTING_CRITERIA = new SortCriterion[0];

    final private String defaultHqlOrderBy = toHqlOrderBy(getDefaultSortCriteria());

    /**
     * Returns a HQL <code>order by</code> clause given some {@link SortCriterion}s.
     * 
     * @param sortCriteria {@link SortCriterion} instances.
     * @return a {@link String}.
     */
    final public static String toHqlOrderBy(SortCriterion... sortCriteria) {

        String string = "";

        if (sortCriteria.length > 0) {

            StringBuilder builder = new StringBuilder(" ORDER BY ");

            for (int i = 0; i < sortCriteria.length - 1; i++) {
                builder.append(sortCriteria.toString());
                builder.append(", ");
            }

            builder.append(sortCriteria[sortCriteria.length - 1]);

            string = builder.toString();

        }

        return string;

    }

    /**
     * Constructor that takes a {@link Class} and a {@link SessionFactory}.
     * 
     * @param clasz a {@link Class}.
     * @param sessionFactory a {@link SessionFactory}. It cannot be null.
     */
    @SuppressWarnings("unchecked")
    public ReadableDAOImpl(SessionFactory sessionFactory) {
        super(null, sessionFactory);
    }

    /**
     * Constructor that takes a {@link Class} and a {@link SessionFactory}.
     * 
     * @param clasz a {@link Class}.
     * @param sessionFactory a {@link SessionFactory}. It cannot be null.
     */
    @SuppressWarnings("unchecked")
    public ReadableDAOImpl(Class<T> clasz, SessionFactory sessionFactory) {
        super(clasz, sessionFactory);
    }

    /**
     * @see br.com.arsmachina.dao.ReadableDAO#countAll()
     */
    public int countAll() {

        final Criteria criteria = createCriteria();

        criteria.setProjection(Projections.rowCount());

        return (Integer) criteria.uniqueResult();

    }

    /**
     * Returns all the entity class' objects. They are sorted according to
     * {@link #getDefaultSortCriterions()}.
     * 
     * @see br.com.arsmachina.dao.ReadableDAO#findAll()
     * @see #getDefaultSortCriterions()
     */
    @SuppressWarnings("unchecked")
    public List<T> findAll() {

        Criteria criteria = createCriteria();
        addSortCriteria(criteria, getDefaultSortCriteria());
        return criteria.list();

    }

    /**
     * @see br.com.arsmachina.dao.ReadableDAO#findById(java.io.Serializable)
     */
    @SuppressWarnings("unchecked")
    public T findById(K id) {
        return (T) getSession().get(getEntityClass(), id);
    }

    /**
     * @see br.com.arsmachina.dao.ReadableDAO#findByIds(K[])
     */
    @SuppressWarnings("unchecked")
    public List<T> findByIds(K... ids) {

        Criteria criteria = createCriteria();
        criteria.add(Restrictions.in(getPrimaryKeyPropertyName(), ids));
        return criteria.list();

    }

    /**
     * @see br.com.arsmachina.dao.ReadableDAO#findByExample(java.lang.Object)
     */
    @SuppressWarnings("unchecked")
    public List<T> findByExample(T example) {

        Criteria criteria = createCriteria();

        if (example != null) {
            criteria.add(createExample(example));
        }

        return criteria.list();

    }

    /**
     * @see br.com.arsmachina.dao.WriteableDAO#refresh(java.lang.Object)
     */
    public void refresh(T object) {
        getSession().refresh(object);
    }

    /**
     * If <code>sortingConstraints</code> is <code>null</code> or empty, this implementation
     * sort the results by the {@link SortCriterion}s returned by
     * {@link #getDefaultSortCriterions()}.
     * 
     * @see br.com.arsmachina.dao.ReadableDAO#findAll(int, int,
     * br.com.arsmachina.dao.SortCriterion[])
     */
    @SuppressWarnings("unchecked")
    public List<T> findAll(int firstResult, int maximumResults, SortCriterion... sortingConstraints) {

        Criteria criteria = createCriteria();
        criteria.setFirstResult(firstResult);
        criteria.setMaxResults(maximumResults);

        if (sortingConstraints == null || sortingConstraints.length == 0) {
            sortingConstraints = getDefaultSortCriteria();
        }

        addSortCriteria(criteria, sortingConstraints);

        return criteria.list();

    }

    /**
     * Reattaches the object to the current {@link org.hibernate.Session} using
     * <code>Session.lock(object, LockMode.NONE)</code> and then returns the object.
     * 
     * @param a <code>T</code>.
     * @return <code>object</code>.
     * @see br.com.arsmachina.dao.ReadableDAO#reattach(java.lang.Object)
     */
    public T reattach(T object) {

        getSession().lock(object, LockMode.NONE);
        return object;

    }

    /**
     * Adds <code>sortCriteria</code> to a {@link Criteria} instance.
     * 
     * @param criteria a {@link Criteria}. It cannot be null.
     * @param sortCriteria a {@link SortCriterion}<code>...</code>. It cannot be null.
     * @todo Support for property paths, not just property names.
     */
    final public void addSortCriteria(Criteria criteria, SortCriterion... sortCriteria) {

        assert criteria != null;

        if (sortCriteria == null || sortCriteria.length == 0) {
            sortCriteria = getDefaultSortCriteria();
        }

        for (SortCriterion sortingConstraint : sortCriteria) {

            final String property = sortingConstraint.getProperty();
            final boolean ascending = sortingConstraint.isAscending();
            final Order order = ascending ? Order.asc(property) : Order.desc(property);
            criteria.addOrder(order);

        }

    }

    /**
     * Adds the default sort criteria to a {@link Criteria} instance. This method just does
     * <code>addSortCriteria(criteria, getDefaultSortCriteria());</code>.
     * 
     * @param criteria a {@link Criteria}. It cannot be null.
     */
    protected void addSortCriteria(Criteria criteria) {
        addSortCriteria(criteria, getDefaultSortCriteria());
    }

    /**
     * Returns the default {@link SortCriterion}s to be used to sort the objects lists returned by
     * methods like {@link #findAll()} and {@link #findAll(int, int, SortCriterion...)} when no
     * sorting constraints are given. This implementation returns {@link #EMPTY_SORTING_CRITERIA}.
     * 
     * @return a {@link SortCriterion} array. It cannot be <code>null</code>.
     */
    public SortCriterion[] getDefaultSortCriteria() {
        return EMPTY_SORTING_CRITERIA;
    }

    /**
     * Creates a {@link Criteria} for this entity class.
     * 
     * @return a {@link Criteria}.
     */
    public Criteria createCriteria() {
        return getSession().createCriteria(getEntityClass());
    }

    /**
     * Creates a {@link Criteria} for this entity class with given sort criteria.
     * 
     * @return a {@link Criteria}.
     */
    public Criteria createCriteria(SortCriterion... sortCriteria) {

        Criteria criteria = createCriteria();
        addSortCriteria(criteria, sortCriteria);
        return criteria;

    }

    /**
     * Creates a {@link Criteria} for this entity class with given sort criteria,
     * first result index and maximum number of results. 
     * 
     * @return a {@link Criteria}.
     */
    public Criteria createCriteria(int firstIndex, int maximumResults, SortCriterion... sortCriteria) {

        Criteria criteria = createCriteria(sortCriteria);
        criteria.setFirstResult(firstIndex);
        criteria.setMaxResults(maximumResults);
        return criteria;

    }

    /**
     * Used by {@link #findByExample(Object)} to create an {@link Example} instance.
     * 
     * @todo add criteria for property types not handled by Example (primary keys, associations,
     * etc)
     * @return an {@link Example}.
     */
    public Example createExample(T entity) {

        Example example = Example.create(entity);
        example.enableLike(MatchMode.ANYWHERE);
        example.excludeZeroes();
        example.ignoreCase();

        return example;

    }

    /**
     * Returns the value of the <code>defaultHqlOrderBy</code> property.
     * 
     * @return a {@link String}.
     */
    public final String getDefaultHqlOrderBy() {
        return defaultHqlOrderBy;
    }

}