All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.discursive.dao.generic.hibernate.GenericHibernate Maven / Gradle / Ivy

The newest version!
package com.discursive.dao.generic.hibernate;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.NotImplementedException;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.discursive.dao.generic.GenericDao;
import com.discursive.dao.generic.spring.FinderIntroductionInterceptor;

@SuppressWarnings("unchecked")
public class GenericHibernate extends HibernateDaoSupport implements GenericDao,
        FinderExecutor {

    @SuppressWarnings("unchecked")
	private Class persistentClass;

    @SuppressWarnings("unchecked")
	public GenericHibernate(Class persistentClass) {
        this.persistentClass = persistentClass;
    }

    @SuppressWarnings("unchecked")
    public T byId(ID id) {
        return byId(id, false);
    }

    @SuppressWarnings("unchecked")
    public T byId(ID id, boolean lock) {
        T entity;
        if (lock) {
            entity = (T) getHibernateTemplate().get(getPersistentClass(), id, org.hibernate.LockMode.UPGRADE);
        } else {
            entity = (T) getHibernateTemplate().get(getPersistentClass(), id);
        }
        if( entity != null ) {
            getHibernateTemplate().refresh(entity);
        }
        return entity;
    }

    @SuppressWarnings("unchecked")
    public List all() {
        return getHibernateTemplate().loadAll(getPersistentClass());
    }

    @SuppressWarnings("unchecked")
    public List byExample(T exampleInstance, String... excludeProperty) {
        HibernateCallback callback = generateExampleCallback(exampleInstance, excludeProperty);
        return (List) getHibernateTemplate().execute(callback);
    }

    HibernateCallback generateExampleCallback(final T exampleInstance, final String... excludeProperty) {
        HibernateCallback callback = new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                // Using Hibernate, more difficult with EntityManager and EJB-QL
                Criteria crit = session.createCriteria(getPersistentClass());
                Example example = Example.create(exampleInstance);
                for (String exclude : excludeProperty) {
                    example.excludeProperty(exclude);
                }
                crit.add(example);
                return crit.list();
            }

        };
        return callback;
    }

    @SuppressWarnings("unchecked")
    public T oneByExample(T exampleInstance, String... excludeProperty) {
        HibernateCallback callback = generateOneByExampleCallback(exampleInstance, excludeProperty);
        return (T) getHibernateTemplate().execute(callback);
    }

    HibernateCallback generateOneByExampleCallback(final T exampleInstance, final String... excludeProperty) {
        HibernateCallback callback = new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                // Using Hibernate, more difficult with EntityManager and EJB-QL
                Criteria crit = session.createCriteria(getPersistentClass());
                Example example = Example.create(exampleInstance);
                for (String exclude : excludeProperty) {
                    example.excludeProperty(exclude);
                }
                crit.add(example);
                return crit.uniqueResult();
            }

        };
        return callback;
    }

    @SuppressWarnings("unchecked")
    public T makePersistent(T entity) {
        return (T) getHibernateTemplate().merge(entity);
    }

    public T makeTransient(T entity) {
        getHibernateTemplate().delete(entity);
        return entity;
    }

    public Collection makeTransient(Collection entities) {
        getHibernateTemplate().deleteAll(entities);
        return entities;
    }

    public Class getPersistentClass() {
        return persistentClass;
    }

    /**
     * Use this inside subclasses as a convenience method.
     */
    @SuppressWarnings("unchecked")
    List findByCriteria(final Criterion... criterion) {
        HibernateCallback callback = generateCriteriaCallback(criterion);
        return (List) getHibernateTemplate().execute(callback);
    }

    HibernateCallback generateCriteriaCallback(final Criterion... criterion) {
        HibernateCallback callback = new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Criteria crit = session.createCriteria(getPersistentClass());
                for (Criterion c : criterion) {
                    crit.add(c);
                }
                return crit.list();
            }
        };
        return callback;
    }

    /**
     * Use this inside subclasses as a convenience method.
     */
    @SuppressWarnings("unchecked")
    protected T findUniqueByCriteria(final Criterion... criterion) {
        HibernateCallback callback = new HibernateCallback() {
            public T doInHibernate(Session session) throws HibernateException, SQLException {
                Criteria crit = session.createCriteria(getPersistentClass());
                for (Criterion c : criterion) {
                    crit.add(c);
                }
                return (T) crit.uniqueResult();
            }
        };
        return (T) getHibernateTemplate().execute(callback);
    }

    @SuppressWarnings("unchecked")
    public List executeFinder(Method method, final Object[] queryArgs, LockMode lockMode) {
        final String queryName = queryNameFromMethod(method);
        final Query namedQuery = getQuery(queryName);
        for (int i = 0; i < queryArgs.length; i++) {
            Object arg = queryArgs[i];
            setParameter(namedQuery, i, arg);
        }
        namedQuery.setLockMode( "obj", lockMode );
        return (List) namedQuery.list();
    }

    @SuppressWarnings("unchecked")
    public Iterator executeIterator(Method method, final Object[] queryArgs, LockMode lockMode) {
        final String queryName = queryNameFromMethod(method);
        final Query namedQuery = getQuery(queryName);
        for (int i = 0; i < queryArgs.length; i++) {
            Object arg = queryArgs[i];
            setParameter(namedQuery, i, arg);
        }
        namedQuery.setLockMode( "obj", lockMode );
        return (Iterator) namedQuery.iterate();
    }
    
    @SuppressWarnings("unchecked")    
    public Long executeCount(Method method, final Object[] queryArgs, LockMode lockMode) {
    	final String queryName = queryNameFromMethod(method);
    	final Query namedQuery = getQuery(queryName);
    	String qString         = namedQuery.getQueryString();
    	if(!qString.trim().toLowerCase().startsWith("from")) 
    		throw new NotImplementedException("GenericHibernate cannot perform count queries on NamedQueries that do NOT start with 'from'. The named query is: " + qString);
    	String newQuery = "select count(*) " + qString;
    	Query q = getSession().createQuery(newQuery);

    	
    	for (int i = 0; i < queryArgs.length; i++) {
    		Object arg = queryArgs[i];
            setParameter(q, i, arg);
        }

    	// don't set the lock mode - we don't want to lock for counts and it causes exceptions anyway.
    	//      q.setLockMode( "obj", lockMode );
        Long count = (Long) q.iterate().next();
        return count;
    }

    @SuppressWarnings("unchecked")
    public ScrollableResults executeScroller(Method method, final Object[] queryArgs, LockMode lockMode) {
        final String queryName = queryNameFromMethod(method);
        final Query namedQuery = getQuery(queryName);
        for (int i = 0; i < queryArgs.length; i++) {
            Object arg = queryArgs[i];
            setParameter(namedQuery, i, arg);
        }
        namedQuery.setLockMode( "obj", lockMode );
        return (ScrollableResults) namedQuery.scroll();
    }

    @SuppressWarnings("unchecked")
    public T executeUnique(Method method, final Object[] queryArgs, LockMode lockMode) {
        final String queryName = queryNameFromMethod(method);
        final Query namedQuery = getQuery(queryName);
        for (int i = 0; i < queryArgs.length; i++) {
            Object arg = queryArgs[i];
            setParameter(namedQuery, i, arg);
        }
        namedQuery.setLockMode( "obj", lockMode );
        Object result = namedQuery.uniqueResult();
       	return (T) result;
    }

	private void setParameter(final Query namedQuery, int i, Object arg) {
		if( arg instanceof Object[] ) {
			namedQuery.setParameterList("param"+i, (Object[]) arg);
		} else if( arg instanceof Collection ) {
			namedQuery.setParameterList("param"+i, (Collection) arg);
		} else {
			namedQuery.setParameter("param"+i, arg);
			// namedQuery.setParameter(i, arg);			
		}
	}
	
    public String queryNameFromMethod(Method finderMethod) {
        String name  = finderMethod.getName();
        boolean done = false;
        while (!done) {
        	String lname = name.toLowerCase();
        	if(lname.startsWith(FinderIntroductionInterceptor.COUNT))
        		name = name.substring(FinderIntroductionInterceptor.COUNT.length());
        	else if(lname.startsWith(FinderIntroductionInterceptor.FIND))
        		name = name.substring(FinderIntroductionInterceptor.FIND.length());
        	else if(lname.startsWith(FinderIntroductionInterceptor.ITERATE))
        		name = name.substring(FinderIntroductionInterceptor.ITERATE.length());
        	else if(lname.startsWith(FinderIntroductionInterceptor.LOCK))
        		name = name.substring(FinderIntroductionInterceptor.LOCK.length());
        	else if(lname.startsWith(FinderIntroductionInterceptor.SCROLL))
        		name = name.substring(FinderIntroductionInterceptor.SCROLL.length());
        	else if(lname.startsWith(FinderIntroductionInterceptor.UNIQUE))
        		name = name.substring(FinderIntroductionInterceptor.UNIQUE.length());
        	else 
        		done = true;
        }

        return persistentClass.getSimpleName() + "." + name;
    }

    Query getQuery(String queryName) {
        if (queryName.toLowerCase().endsWith("all")) {
            return getSession().createQuery("from " + persistentClass.getName() + " obj");
        } else {
            return getSession().getNamedQuery(queryName);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy