com.mg.framework.api.orm.OrmTemplate.java Source code

Java tutorial

Introduction

Here is the source code for com.mg.framework.api.orm.OrmTemplate.java

Source

/*
 * OrmTemplate.java
 *
 * Copyright (c) 1998 - 2005 BusinessTechnology, Ltd.
 * All rights reserved
 *
 * This program is the proprietary and confidential information
 * of BusinessTechnology, Ltd. and may be used and disclosed only
 * as authorized in a license agreement authorizing and
 * controlling such use and disclosure
 *
 * Millennium Business Suite Anywhere System.
 *
 */
package com.mg.framework.api.orm;

import com.mg.framework.api.DataAccessException;
import com.mg.framework.api.Logger;
import com.mg.framework.service.PersistentManagerHibernateImpl;
import com.mg.framework.service.SQLExceptionTranslatorManagerLocator;
import com.mg.framework.support.orm.CriteriaHibernateImpl;
import com.mg.framework.support.orm.OrmTemplateHibernateImpl;
import com.mg.framework.utils.ServerUtils;

import org.hibernate.HibernateException;
import org.hibernate.JDBCException;
import org.hibernate.Query;
import org.hibernate.Session;

import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 *  ?  ?
 *
 * @author Oleg V. Safonov
 * @version $Id: OrmTemplate.java,v 1.9 2007/07/27 09:32:16 safonov Exp $
 */
public abstract class OrmTemplate {
    private Logger logger = ServerUtils.getLogger(getClass());
    private Session session = null;
    private boolean cacheQueries;
    private String queryCacheRegion;
    private int fetchSize;
    private int maxResults;
    private FlushMode flushMode;

    /**
     *  ?? 
     */
    public static OrmTemplate getInstance() {
        return new OrmTemplateHibernateImpl();
    }

    /**
     * ? ??  ? ?? ??  ? ?? ??
     *
     * @param persistentClass ?? ??
     * @return 
     */
    public static Criteria createCriteria(Class<?> persistentClass) {
        return createCriteria(persistentClass.getName());
    }

    /**
     * ? ??  ? ??
     *
     * @param entityName ? ?? ??
     * @return 
     */
    public static Criteria createCriteria(String entityName) {
        return ServerUtils.getPersistentManager().createCriteria(entityName);
    }

    /**
     * ? ??  ? ?? ??  ? ?? ?? ? 
     * ?
     *
     * @param persistentClass ?? ??
     * @param alias           ?
     * @return 
     */
    public static Criteria createCriteria(Class<?> persistentClass, String alias) {
        return createCriteria(persistentClass.getName(), alias);
    }

    /**
     * ? ??  ? ?? ?  ?
     *
     * @param entityName ? ?? ??
     * @param alias      ?
     * @return 
     */
    public static Criteria createCriteria(String entityName, String alias) {
        try {
            return new CriteriaHibernateImpl(PersistentManagerHibernateImpl.getFactory().getCurrentSession()
                    .createCriteria(entityName, alias));
        } catch (HibernateException e) {
            throw new DataAccessException(e);
        }
    }

    private static DataAccessException convertHibernateAccessException(HibernateException ex) {
        if (ex instanceof JDBCException)
            return convertJdbcAccessException(((JDBCException) ex).getSQLException());
        else
            return new DataAccessException(ex);
    }

    /**
     * Convert the given SQLException to an appropriate exception from the
     * <code>com.mg.framework.api</code> hierarchy. Can be overridden in subclasses. <p>Note that a
     * direct SQLException can just occur here when callback code performs direct JDBC access via
     * <code>Session.connection()</code>.
     *
     * @param ex SQLException that occured
     * @return the corresponding DataAccessException instance
     * @see #setJdbcExceptionTranslator
     * @see org.hibernate.Session#connection()
     */
    private static DataAccessException convertJdbcAccessException(SQLException ex) {
        return SQLExceptionTranslatorManagerLocator.locate().translate(ex);
    }

    /**
     * Apply the given name parameter to the given Query object.
     *
     * @param queryObject the Query object
     * @param paramName   the name of the parameter
     * @param value       the value of the parameter
     * @throws HibernateException if thrown by the Query object
     */
    protected void applyNamedParameterToQuery(Query queryObject, String paramName, Object value)
            throws HibernateException {
        if (value instanceof Collection) {
            queryObject.setParameterList(paramName, (Collection) value);
        } else if (value instanceof Object[]) {
            queryObject.setParameterList(paramName, (Object[]) value);
        } else {
            queryObject.setParameter(paramName, value);
        }
    }

    protected Session getSession() {
        if (session != null)
            return session;
        else
            return PersistentManagerHibernateImpl.getFactory().getCurrentSession();
    }

    /**
     * Set Hibernate session. Use for standalone test only. Do not use in application server
     * environment.
     */
    public void setSession(Session session) {
        this.session = session;
    }

    /**
     * Execute the action specified by the given action object within a Session.
     *
     * @param action callback object that specifies the Hibernate action to callback code
     * @return a result object returned by the action, or null
     * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
     */
    private <T> T execute(HibernateCallback<T> action) throws DataAccessException {
        Session session = getSession();
        try {
            Session sessionToExpose = session;
            T result = action.doInHibernate(sessionToExpose);
            return result;
        } catch (HibernateException ex) {
            throw convertHibernateAccessException(ex);
        } catch (SQLException ex) {
            throw convertJdbcAccessException(ex);
        } catch (RuntimeException ex) {
            // callback code threw application exception
            throw ex;
        }
    }

    /**
     * Prepare the given Query object, applying cache settings and/or a transaction timeout.
     *
     * @param queryObject the Query object to prepare
     * @see #setCacheQueries
     * @see #setQueryCacheRegion
     */
    protected abstract void prepareQuery(Query queryObject);

    /**
     * Prepare the given Criteria object, applying cache settings and/or a transaction timeout.
     *
     * @param criteria the Criteria object to prepare
     * @see #setCacheQueries
     * @see #setQueryCacheRegion
     */
    protected abstract void prepareCriteria(Criteria criteria);

    /**
     * Return whether to cache all queries executed by this template.
     */
    public boolean isCacheQueries() {
        return cacheQueries;
    }

    /**
     * Set whether to cache all queries executed by this template. If this is true, all Query and
     * Criteria objects created by this template will be marked as cacheable (including all queries
     * through find methods). <p>To specify the query region to be used for queries cached by this
     * template, set the "queryCacheRegion" property.
     *
     * @see #setQueryCacheRegion
     * @see org.hibernate.Query#setCacheable
     * @see org.hibernate.Criteria#setCacheable
     */
    public void setCacheQueries(boolean cacheQueries) {
        this.cacheQueries = cacheQueries;
    }

    /**
     * Return the name of the cache region for queries executed by this template.
     */
    public String getQueryCacheRegion() {
        return queryCacheRegion;
    }

    /**
     * Set the name of the cache region for queries executed by this template. If this is specified,
     * it will be applied to all Query and Criteria objects created by this template (including all
     * queries through find methods). <p>The cache region will not take effect unless queries created
     * by this template are configured to be cached via the "cacheQueries" property.
     *
     * @see #setCacheQueries
     * @see org.hibernate.Query#setCacheRegion
     * @see org.hibernate.Criteria#setCacheRegion
     */
    public void setQueryCacheRegion(String queryCacheRegion) {
        this.queryCacheRegion = queryCacheRegion;
    }

    /**
     * Return the fetch size specified for this OrmTemplate.
     */
    public int getFetchSize() {
        return fetchSize;
    }

    /**
     * Set the fetch size for this OrmTemplate. This is important for processing large result sets:
     * Setting this higher than the default value will increase processing speed at the cost of memory
     * consumption; setting this lower can avoid transferring row data that will never be read by the
     * application. <p>Default is 0, indicating to use the JDBC driver's default.
     */
    public void setFetchSize(int fetchSize) {
        this.fetchSize = fetchSize;
    }

    /**
     * Return the maximum number of rows specified for this OrmTemplate.
     */
    public int getMaxResults() {
        return maxResults;
    }

    /**
     * Set the maximum number of rows for this OrmTemplate. This is important for processing subsets
     * of large result sets, avoiding to read and hold the entire result set in the database or in the
     * JDBC driver if we're never interested in the entire result in the first place (for example,
     * when performing searches that might return a large number of matches). <p>Default is 0,
     * indicating to use the JDBC driver's default.
     */
    public void setMaxResults(int maxResults) {
        this.maxResults = maxResults;
    }

    /**
     * Return the FlushMode specified for this OrmTemplate.
     *
     * @return flushMode or <code>null<code> if not set
     */
    public FlushMode getFlushMode() {
        return flushMode;
    }

    /**
     * Set the flush mode for this OrmTemplate
     *
     * @param flushMode flushMode for this OrmTemplate
     */
    public void setFlushMode(FlushMode flushMode) {
        this.flushMode = flushMode;
    }

    /**
     * ?  EJBQL ?
     *
     * @param <T>              
     * @param persistentClass ?? 
     * @param queryString     ? ?
     * @return  ?
     */
    @SuppressWarnings("unchecked") //$NON-NLS-1$
    public <T> List<T> find(final Class<T> persistentClass, String queryString) {
        return find(queryString, (Object[]) null);
    }

    /**
     * ?  EJBQL ?
     *
     * @param queryString ? ?
     * @return  ?
     */
    public List find(String queryString) {
        return find(queryString, (Object[]) null);
    }

    /**
     * ?  EJBQL ?  
     *
     * @param queryString ? ?
     * @param value        
     * @return  ?
     */
    public List find(String queryString, Object value) {
        return find(queryString, new Object[] { value });
    }

    /**
     * ?  EJBQL ?  
     *
     * @param queryString ? ?
     * @param values      ? 
     * @return  ?
     */
    public List find(final String queryString, final Object[] values) {
        return (List) execute(new HibernateCallback<List>() {
            public List doInHibernate(Session session) throws HibernateException {
                Query queryObject = session.createQuery(queryString);
                prepareQuery(queryObject);
                if (values != null) {
                    for (int i = 0; i < values.length; i++) {
                        queryObject.setParameter(i, values[i]);
                    }
                }
                return queryObject.list();
            }
        });
    }

    /**
     * ?  EJBQL ?   
     *
     * @param queryString ? ?
     * @param paramName   ? 
     * @param value        
     * @return  ?
     */
    public List findByNamedParam(String queryString, String paramName, Object value) {
        return findByNamedParam(queryString, new String[] { paramName }, new Object[] { value });
    }

    /**
     * ?  EJBQL ?   
     *
     * @param queryString ? ?
     * @param paramNames   
     * @param values      ? 
     * @return  ?
     */
    public List findByNamedParam(final String queryString, final String[] paramNames, final Object[] values) {
        return findByNamedParam(queryString, paramNames, values, null);
    }

    private void setResultTransformer(final Query queryObject, final ResultTransformer resultTransformer) {
        if (resultTransformer != null) {
            queryObject.setResultTransformer(new org.hibernate.transform.ResultTransformer() {

                public List transformList(List collection) {
                    return collection;
                }

                public Object transformTuple(Object[] tuple, String[] aliases) {
                    return resultTransformer.transformTuple(tuple, aliases);
                }

            });
        }
    }

    /**
     * ?  EJBQL ?   
     *
     * @param queryString       ? ?
     * @param paramNames         
     * @param values            ? 
     * @param resultTransformer ?? ?   ?
     * @return  ?
     */
    public <T> List<T> findByNamedParam(final String queryString, final String[] paramNames, final Object[] values,
            final ResultTransformer<T> resultTransformer) {
        if (paramNames.length != values.length) {
            throw new IllegalArgumentException("Length of paramNames array must match length of values array"); //$NON-NLS-1$
        }
        return (List<T>) execute(new HibernateCallback<List<T>>() {
            @SuppressWarnings("unchecked")
            public List<T> doInHibernate(Session session) throws HibernateException {
                Query queryObject = session.createQuery(queryString);
                setResultTransformer(queryObject, resultTransformer);
                prepareQuery(queryObject);
                if (values != null) {
                    for (int i = 0; i < values.length; i++) {
                        applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
                    }
                }
                return queryObject.list();
            }
        });
    }

    /**
     * ?  EJBQL ?   
     *
     * @param queryString ? ?
     * @param params       ?  - 
     * @return  ?
     */
    public List findByNamedParam(final String queryString, final Map<String, Object> params) {
        return (List) execute(new HibernateCallback<List>() {
            public List doInHibernate(Session session) throws HibernateException {
                Query queryObject = session.createQuery(queryString);
                prepareQuery(queryObject);
                queryObject.setProperties(params);
                return queryObject.list();
            }
        });
    }

    /**
     * ?   EJBQL ?
     *
     * @param queryName ? ?
     * @return  ?
     */
    public List findByNamedQuery(String queryName) {
        return findByNamedQuery(queryName, (Object[]) null);
    }

    /**
     * ?   EJBQL ?  
     *
     * @param queryName ? ?
     * @param value      
     * @return  ?
     */
    public List findByNamedQuery(String queryName, Object value) {
        return findByNamedQuery(queryName, new Object[] { value });
    }

    /**
     * ?   EJBQL ?  
     *
     * @param queryName ? ?
     * @param values    ? 
     * @return  ?
     */
    public List findByNamedQuery(final String queryName, final Object[] values) {
        return (List) execute(new HibernateCallback<List>() {
            public List doInHibernate(Session session) throws HibernateException {
                Query queryObject = session.getNamedQuery(queryName);
                prepareQuery(queryObject);
                if (values != null) {
                    for (int i = 0; i < values.length; i++) {
                        queryObject.setParameter(i, values[i]);
                    }
                }
                return queryObject.list();
            }
        });
    }

    /**
     * ?   EJBQL ?   
     *
     * @param queryName ? ?
     * @param paramName ? 
     * @param value      
     * @return  ?
     */
    public List findByNamedQueryAndNamedParam(String queryName, String paramName, Object value) {
        return findByNamedQueryAndNamedParam(queryName, new String[] { paramName }, new Object[] { value });
    }

    public List findByNamedQueryAndNamedParam(final String queryName, final String[] paramNames,
            final Object[] values) {
        return findByNamedQueryAndNamedParam(queryName, paramNames, values, null);
    }

    /**
     * ?   EJBQL ?   
     *
     * @param queryName  ? ?
     * @param paramNames  
     * @param values     ? 
     * @return  ?
     */
    public <T> List<T> findByNamedQueryAndNamedParam(final String queryName, final String[] paramNames,
            final Object[] values, final ResultTransformer<T> resultTransformer) {

        if (paramNames != null && values != null && paramNames.length != values.length) {
            throw new IllegalArgumentException("Length of paramNames array must match length of values array");
        }
        return (List<T>) execute(new HibernateCallback<List<T>>() {
            @SuppressWarnings("unchecked")
            public List<T> doInHibernate(Session session) throws HibernateException {
                Query queryObject = session.getNamedQuery(queryName);
                setResultTransformer(queryObject, resultTransformer);
                prepareQuery(queryObject);
                if (values != null) {
                    for (int i = 0; i < values.length; i++) {
                        applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
                    }
                }
                return queryObject.list();
            }
        });
    }

    /**
     * ?   EJBQL ?   
     *
     * @param queryName ? ?
     * @param params     ?  - 
     * @return  ?
     */
    public List findByNamedQueryAndNamedParam(final String queryName, final Map<String, Object> params) {
        return (List) execute(new HibernateCallback<List>() {
            public List doInHibernate(Session session) throws HibernateException {
                Query queryObject = session.getNamedQuery(queryName);
                prepareQuery(queryObject);
                queryObject.setProperties(params);
                return queryObject.list();
            }
        });
    }

    /**
     * ?  ?
     *
     * @param <T>       
     * @param criteria 
     * @return  ?
     */
    @SuppressWarnings("unchecked") //$NON-NLS-1$
    public <T> List<T> findByCriteria(final Criteria criteria) {
        return execute(new HibernateCallback<List<T>>() {
            public List<T> doInHibernate(Session session) throws HibernateException {
                return ((CriteriaHibernateImpl) criteria).getDelegate().list();
            }
        });
    }

    /**
     * ?    ?
     *
     * @param <T>       
     * @param criteria 
     * @return   <code>null</code> ?  
     */
    @SuppressWarnings("unchecked") //$NON-NLS-1$
    public <T> T findUniqueByCriteria(final Criteria criteria) {
        return execute(new HibernateCallback<T>() {
            public T doInHibernate(Session session) throws HibernateException {
                return (T) ((CriteriaHibernateImpl) criteria).getDelegate().uniqueResult();
            }
        });
    }

    /**
     * ?  ?? 
     *
     * @param <T>              
     * @param persistentClass ?? 
     * @param criteria        ?? 
     * @return  ?
     */
    public <T> List<T> findByCriteria(final Class<T> persistentClass, final Criterion... criteria) {
        if (criteria.length == 0)
            throw new IllegalArgumentException("List of criteria is empty"); //$NON-NLS-1$
        Criteria crit = OrmTemplate.createCriteria(persistentClass);
        for (Criterion c : criteria)
            crit.add(c);
        return findByCriteria(crit);
    }

    /**
     * ?    ?? 
     *
     * @param <T>              
     * @param persistentClass ?? 
     * @param criteria        ?? 
     * @return   <code>null</code> ?  
     */
    @SuppressWarnings("unchecked")
    public <T> T findUniqueByCriteria(final Class<T> persistentClass, final Criterion... criteria) {
        if (criteria.length == 0)
            throw new IllegalArgumentException("List of criteria is empty"); //$NON-NLS-1$
        Criteria crit = OrmTemplate.createCriteria(persistentClass);
        for (Criterion c : criteria)
            crit.add(c);
        return (T) findUniqueByCriteria(crit);
    }

    /**
     * Execute the update or delete statement. </p> The semantics are compliant with the ejb3
     * Query.executeUpdate() method.
     *
     * @param queryString query text
     * @return The number of entities updated or deleted.
     */
    public int bulkUpdate(final String queryString) {
        //      Integer deleteCount = execute(new HibernateCallback<Integer>() {
        //         public Integer doInHibernate(Session session) throws HibernateException {
        //            Query queryObject = session.createQuery(queryString);
        //            prepareQuery(queryObject);
        //            return queryObject.executeUpdate();
        //         }
        //      });
        //      return deleteCount.intValue();
        return bulkUpdate(queryString, new String[] {}, new Object[] {});
    }

    /**
     * Execute the update or delete statement. </p> The semantics are compliant with the ejb3
     * Query.executeUpdate() method.
     *
     * @param queryString query text
     * @param paramName   the name of the parameter
     * @param value       the value of the parameter
     * @return The number of entities updated or deleted.
     */
    public int bulkUpdate(final String queryString, final String paramName, final Object value) {
        return bulkUpdate(queryString, new String[] { paramName }, new Object[] { value });
    }

    /**
     * Execute the update or delete statement. </p> The semantics are compliant with the ejb3
     * Query.executeUpdate() method.
     *
     * @param queryString query text
     * @param paramNames  the parameters' names
     * @param values      the parameters' values
     * @return The number of entities updated or deleted.
     */
    public int bulkUpdate(final String queryString, final String[] paramNames, final Object[] values) {
        if (paramNames.length != values.length) {
            throw new IllegalArgumentException("Length of paramNames array must match length of values array"); //$NON-NLS-1$
        }
        Integer deleteCount = execute(new HibernateCallback<Integer>() {
            public Integer doInHibernate(Session session) throws HibernateException {
                Query queryObject = session.createQuery(queryString);
                prepareQuery(queryObject);
                if (values != null) {
                    for (int i = 0; i < values.length; i++) {
                        applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
                    }
                }
                return queryObject.executeUpdate();
            }
        });
        return deleteCount.intValue();
    }

    /**
     * Execute the update or delete statement. </p> The semantics are compliant with the ejb3
     * Query.executeUpdate() method.
     *
     * @param queryName query name
     * @return The number of entities updated or deleted.
     */
    public int bulkUpdateByNamedQuery(final String queryName) {
        return bulkUpdateByNamedQuery(queryName, new String[] {}, new Object[] {});
    }

    /**
     * Execute the update or delete statement. </p> The semantics are compliant with the ejb3
     * Query.executeUpdate() method.
     *
     * @param queryName query name
     * @param paramName the name of the parameter
     * @param value     the value of the parameter
     * @return The number of entities updated or deleted.
     */
    public int bulkUpdateByNamedQuery(final String queryName, final String paramName, final Object value) {
        return bulkUpdateByNamedQuery(queryName, new String[] { paramName }, new Object[] { value });
    }

    /**
     * Execute the update or delete statement. </p> The semantics are compliant with the ejb3
     * Query.executeUpdate() method.
     *
     * @param queryName  query name
     * @param paramNames the parameters' names
     * @param values     the parameters' values
     * @return The number of entities updated or deleted.
     */
    public int bulkUpdateByNamedQuery(final String queryName, final String[] paramNames, final Object[] values) {
        if (paramNames.length != values.length) {
            throw new IllegalArgumentException("Length of paramNames array must match length of values array"); //$NON-NLS-1$
        }
        Integer deleteCount = execute(new HibernateCallback<Integer>() {
            public Integer doInHibernate(Session session) throws HibernateException {
                Query queryObject = session.getNamedQuery(queryName);
                prepareQuery(queryObject);
                if (values != null) {
                    for (int i = 0; i < values.length; i++) {
                        applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
                    }
                }
                return queryObject.executeUpdate();
            }
        });
        return deleteCount.intValue();
    }

}