HibernateTemplate 源码

package org.springframework.orm.hibernate3;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.hibernate.Criteria;
import org.hibernate.Filter;
import org.hibernate.FlushMode;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.ReplicationMode;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.util.Assert;

public class HibernateTemplate
  extends HibernateAccessor
  implements HibernateOperations
{
  private boolean allowCreate = true;
  private boolean alwaysUseNewSession = false;
  private boolean exposeNativeSession = false;
  private boolean checkWriteOperations = true;
  private boolean cacheQueries = false;
  private String queryCacheRegion;
  private int fetchSize = 0;
  private int maxResults = 0;
  
  public HibernateTemplate() {}
  
  public HibernateTemplate(SessionFactory sessionFactory)
  {
    setSessionFactory(sessionFactory);
    afterPropertiesSet();
  }
  
  public HibernateTemplate(SessionFactory sessionFactory, boolean allowCreate)
  {
    setSessionFactory(sessionFactory);
    setAllowCreate(allowCreate);
    afterPropertiesSet();
  }
  
  public void setAllowCreate(boolean allowCreate)
  {
    this.allowCreate = allowCreate;
  }
  
  public boolean isAllowCreate()
  {
    return this.allowCreate;
  }
  
  public void setAlwaysUseNewSession(boolean alwaysUseNewSession)
  {
    this.alwaysUseNewSession = alwaysUseNewSession;
  }
  
  public boolean isAlwaysUseNewSession()
  {
    return this.alwaysUseNewSession;
  }
  
  public void setExposeNativeSession(boolean exposeNativeSession)
  {
    this.exposeNativeSession = exposeNativeSession;
  }
  
  public boolean isExposeNativeSession()
  {
    return this.exposeNativeSession;
  }
  
  public void setCheckWriteOperations(boolean checkWriteOperations)
  {
    this.checkWriteOperations = checkWriteOperations;
  }
  
  public boolean isCheckWriteOperations()
  {
    return this.checkWriteOperations;
  }
  
  public void setCacheQueries(boolean cacheQueries)
  {
    this.cacheQueries = cacheQueries;
  }
  
  public boolean isCacheQueries()
  {
    return this.cacheQueries;
  }
  
  public void setQueryCacheRegion(String queryCacheRegion)
  {
    this.queryCacheRegion = queryCacheRegion;
  }
  
  public String getQueryCacheRegion()
  {
    return this.queryCacheRegion;
  }
  
  public void setFetchSize(int fetchSize)
  {
    this.fetchSize = fetchSize;
  }
  
  public int getFetchSize()
  {
    return this.fetchSize;
  }
  
  public void setMaxResults(int maxResults)
  {
    this.maxResults = maxResults;
  }
  
  public int getMaxResults()
  {
    return this.maxResults;
  }
  
  public Object execute(HibernateCallback action)
    throws DataAccessException
  {
    return doExecute(action, false, false);
  }
  
  public List executeFind(HibernateCallback action)
    throws DataAccessException
  {
    Object result = doExecute(action, false, false);
    if ((result != null) && (!(result instanceof List))) {
      throw new InvalidDataAccessApiUsageException("Result object returned from HibernateCallback isn't a List: [" + result + "]");
    }
    return (List)result;
  }
  
  public Object executeWithNewSession(HibernateCallback action)
  {
    return doExecute(action, true, false);
  }
  
  public Object executeWithNativeSession(HibernateCallback action)
  {
    return doExecute(action, false, true);
  }
  
  /**
   * @deprecated
   */
  public Object execute(HibernateCallback action, boolean enforceNativeSession)
    throws DataAccessException
  {
    return doExecute(action, false, enforceNativeSession);
  }
  
  protected Object doExecute(HibernateCallback action, boolean enforceNewSession, boolean enforceNativeSession)
    throws DataAccessException
  {
    Assert.notNull(action, "Callback object must not be null");
    
    org.hibernate.Session session = enforceNewSession ? SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor()) : getSession();
    
    boolean existingTransaction = (!enforceNewSession) && ((!isAllowCreate()) || (SessionFactoryUtils.isSessionTransactional(session, getSessionFactory())));
    if (existingTransaction) {
      this.logger.debug("Found thread-bound Session for HibernateTemplate");
    }
    FlushMode previousFlushMode = null;
    try
    {
      previousFlushMode = applyFlushMode(session, existingTransaction);
      enableFilters(session);
      org.hibernate.Session sessionToExpose = (enforceNativeSession) || (isExposeNativeSession()) ? session : createSessionProxy(session);
      
      Object result = action.doInHibernate(sessionToExpose);
      flushIfNecessary(session, existingTransaction);
      return result;
    }
    catch (HibernateException ex)
    {
      throw convertHibernateAccessException(ex);
    }
    catch (SQLException ex)
    {
      throw convertJdbcAccessException(ex);
    }
    catch (RuntimeException ex)
    {
      throw ex;
    }
    finally
    {
      if (existingTransaction)
      {
        this.logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
        disableFilters(session);
        if (previousFlushMode != null) {
          session.setFlushMode(previousFlushMode);
        }
      }
      else if (isAlwaysUseNewSession())
      {
        SessionFactoryUtils.closeSession(session);
      }
      else
      {
        SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());
      }
    }
  }
  
  protected org.hibernate.Session getSession()
  {
    if (isAlwaysUseNewSession()) {
      return SessionFactoryUtils.getNewSession(getSessionFactory(), getEntityInterceptor());
    }
    if (isAllowCreate()) {
      return SessionFactoryUtils.getSession(getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator());
    }
    if (SessionFactoryUtils.hasTransactionalSession(getSessionFactory())) {
      return SessionFactoryUtils.getSession(getSessionFactory(), false);
    }
    try
    {
      return getSessionFactory().getCurrentSession();
    }
    catch (HibernateException ex)
    {
      throw new DataAccessResourceFailureException("Could not obtain current Hibernate Session", ex);
    }
  }
  
  protected org.hibernate.Session createSessionProxy(org.hibernate.Session session)
  {
    Class[] sessionIfcs = null;
    Class mainIfc = org.hibernate.Session.class;
    if ((session instanceof EventSource)) {
      sessionIfcs = new Class[] { mainIfc, EventSource.class };
    } else if ((session instanceof SessionImplementor)) {
      sessionIfcs = new Class[] { mainIfc, SessionImplementor.class };
    } else {
      sessionIfcs = new Class[] { mainIfc };
    }
    return (org.hibernate.Session)Proxy.newProxyInstance(session.getClass().getClassLoader(), sessionIfcs, new CloseSuppressingInvocationHandler(session));
  }
  
  public Object get(Class entityClass, Serializable id)
    throws DataAccessException
  {
    return get(entityClass, id, null);
  }
  
  public Object get(final Class entityClass, final Serializable id, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        if (lockMode != null) {
          return session.get(entityClass, id, lockMode);
        }
        return session.get(entityClass, id);
      }
    });
  }
  
  public Object get(String entityName, Serializable id)
    throws DataAccessException
  {
    return get(entityName, id, null);
  }
  
  public Object get(final String entityName, final Serializable id, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        if (lockMode != null) {
          return session.get(entityName, id, lockMode);
        }
        return session.get(entityName, id);
      }
    });
  }
  
  public Object load(Class entityClass, Serializable id)
    throws DataAccessException
  {
    return load(entityClass, id, null);
  }
  
  public Object load(final Class entityClass, final Serializable id, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        if (lockMode != null) {
          return session.load(entityClass, id, lockMode);
        }
        return session.load(entityClass, id);
      }
    });
  }
  
  public Object load(String entityName, Serializable id)
    throws DataAccessException
  {
    return load(entityName, id, null);
  }
  
  public Object load(final String entityName, final Serializable id, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        if (lockMode != null) {
          return session.load(entityName, id, lockMode);
        }
        return session.load(entityName, id);
      }
    });
  }
  
  public List loadAll(final Class entityClass)
    throws DataAccessException
  {
    (List)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Criteria criteria = session.createCriteria(entityClass);
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        HibernateTemplate.this.prepareCriteria(criteria);
        return criteria.list();
      }
    });
  }
  
  public void load(final Object entity, final Serializable id)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        session.load(entity, id);
        return null;
      }
    });
  }
  
  public void refresh(Object entity)
    throws DataAccessException
  {
    refresh(entity, null);
  }
  
  public void refresh(final Object entity, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        if (lockMode != null) {
          session.refresh(entity, lockMode);
        } else {
          session.refresh(entity);
        }
        return null;
      }
    });
  }
  
  public boolean contains(final Object entity)
    throws DataAccessException
  {
    Boolean result = (Boolean)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
      {
        return session.contains(entity) ? Boolean.TRUE : Boolean.FALSE;
      }
    });
    return result.booleanValue();
  }
  
  public void evict(final Object entity)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        session.evict(entity);
        return null;
      }
    });
  }
  
  public void initialize(Object proxy)
    throws DataAccessException
  {
    try
    {
      Hibernate.initialize(proxy);
    }
    catch (HibernateException ex)
    {
      throw SessionFactoryUtils.convertHibernateAccessException(ex);
    }
  }
  
  public Filter enableFilter(String filterName)
    throws IllegalStateException
  {
    org.hibernate.Session session = SessionFactoryUtils.getSession(getSessionFactory(), false);
    Filter filter = session.getEnabledFilter(filterName);
    if (filter == null) {
      filter = session.enableFilter(filterName);
    }
    return filter;
  }
  
  public void lock(final Object entity, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        session.lock(entity, lockMode);
        return null;
      }
    });
  }
  
  public void lock(final String entityName, final Object entity, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        session.lock(entityName, entity, lockMode);
        return null;
      }
    });
  }
  
  public Serializable save(final Object entity)
    throws DataAccessException
  {
    (Serializable)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        return session.save(entity);
      }
    });
  }
  
  public Serializable save(final String entityName, final Object entity)
    throws DataAccessException
  {
    (Serializable)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        return session.save(entityName, entity);
      }
    });
  }
  
  public void update(Object entity)
    throws DataAccessException
  {
    update(entity, null);
  }
  
  public void update(final Object entity, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        session.update(entity);
        if (lockMode != null) {
          session.lock(entity, lockMode);
        }
        return null;
      }
    });
  }
  
  public void update(String entityName, Object entity)
    throws DataAccessException
  {
    update(entityName, entity, null);
  }
  
  public void update(final String entityName, final Object entity, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        session.update(entityName, entity);
        if (lockMode != null) {
          session.lock(entity, lockMode);
        }
        return null;
      }
    });
  }
  
  public void saveOrUpdate(final Object entity)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        session.saveOrUpdate(entity);
        return null;
      }
    });
  }
  
  public void saveOrUpdate(final String entityName, final Object entity)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        session.saveOrUpdate(entityName, entity);
        return null;
      }
    });
  }
  
  public void saveOrUpdateAll(final Collection entities)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        for (Iterator it = entities.iterator(); it.hasNext();) {
          session.saveOrUpdate(it.next());
        }
        return null;
      }
    });
  }
  
  public void replicate(final Object entity, final ReplicationMode replicationMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        session.replicate(entity, replicationMode);
        return null;
      }
    });
  }
  
  public void replicate(final String entityName, final Object entity, final ReplicationMode replicationMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        session.replicate(entityName, entity, replicationMode);
        return null;
      }
    });
  }
  
  public void persist(final Object entity)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        session.persist(entity);
        return null;
      }
    });
  }
  
  public void persist(final String entityName, final Object entity)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        session.persist(entityName, entity);
        return null;
      }
    });
  }
  
  public Object merge(final Object entity)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        return session.merge(entity);
      }
    });
  }
  
  public Object merge(final String entityName, final Object entity)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        return session.merge(entityName, entity);
      }
    });
  }
  
  public void delete(Object entity)
    throws DataAccessException
  {
    delete(entity, null);
  }
  
  public void delete(final Object entity, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        if (lockMode != null) {
          session.lock(entity, lockMode);
        }
        session.delete(entity);
        return null;
      }
    });
  }
  
  public void delete(String entityName, Object entity)
    throws DataAccessException
  {
    delete(entityName, entity, null);
  }
  
  public void delete(final String entityName, final Object entity, final LockMode lockMode)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        if (lockMode != null) {
          session.lock(entityName, entity, lockMode);
        }
        session.delete(entityName, entity);
        return null;
      }
    });
  }
  
  public void deleteAll(final Collection entities)
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        HibernateTemplate.this.checkWriteOperationAllowed(session);
        for (Iterator it = entities.iterator(); it.hasNext();) {
          session.delete(it.next());
        }
        return null;
      }
    });
  }
  
  public void flush()
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        session.flush();
        return null;
      }
    });
  }
  
  public void clear()
    throws DataAccessException
  {
    executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
      {
        session.clear();
        return null;
      }
    });
  }
  
  public List find(String queryString)
    throws DataAccessException
  {
    return find(queryString, (Object[])null);
  }
  
  public List find(String queryString, Object value)
    throws DataAccessException
  {
    return find(queryString, new Object[] { value });
  }
  
  public List find(final String queryString, final Object[] values)
    throws DataAccessException
  {
    (List)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Query queryObject = session.createQuery(queryString);
        HibernateTemplate.this.prepareQuery(queryObject);
        if (values != null) {
          for (int i = 0; i < values.length; i++) {
            queryObject.setParameter(i, values[i]);
          }
        }
        return queryObject.list();
      }
    });
  }
  
  public List findByNamedParam(String queryString, String paramName, Object value)
    throws DataAccessException
  {
    return findByNamedParam(queryString, new String[] { paramName }, new Object[] { value });
  }
  
  public List findByNamedParam(final String queryString, final String[] paramNames, final Object[] values)
    throws DataAccessException
  {
    if (paramNames.length != values.length) {
      throw new IllegalArgumentException("Length of paramNames array must match length of values array");
    }
    (List)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Query queryObject = session.createQuery(queryString);
        HibernateTemplate.this.prepareQuery(queryObject);
        if (values != null) {
          for (int i = 0; i < values.length; i++) {
            HibernateTemplate.this.applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
          }
        }
        return queryObject.list();
      }
    });
  }
  
  public List findByValueBean(final String queryString, final Object valueBean)
    throws DataAccessException
  {
    (List)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Query queryObject = session.createQuery(queryString);
        HibernateTemplate.this.prepareQuery(queryObject);
        queryObject.setProperties(valueBean);
        return queryObject.list();
      }
    });
  }
  
  public List findByNamedQuery(String queryName)
    throws DataAccessException
  {
    return findByNamedQuery(queryName, (Object[])null);
  }
  
  public List findByNamedQuery(String queryName, Object value)
    throws DataAccessException
  {
    return findByNamedQuery(queryName, new Object[] { value });
  }
  
  public List findByNamedQuery(final String queryName, final Object[] values)
    throws DataAccessException
  {
    (List)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Query queryObject = session.getNamedQuery(queryName);
        HibernateTemplate.this.prepareQuery(queryObject);
        if (values != null) {
          for (int i = 0; i < values.length; i++) {
            queryObject.setParameter(i, values[i]);
          }
        }
        return queryObject.list();
      }
    });
  }
  
  public List findByNamedQueryAndNamedParam(String queryName, String paramName, Object value)
    throws DataAccessException
  {
    return findByNamedQueryAndNamedParam(queryName, new String[] { paramName }, new Object[] { value });
  }
  
  public List findByNamedQueryAndNamedParam(final String queryName, final String[] paramNames, final Object[] values)
    throws DataAccessException
  {
    if ((paramNames != null) && (values != null) && (paramNames.length != values.length)) {
      throw new IllegalArgumentException("Length of paramNames array must match length of values array");
    }
    (List)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Query queryObject = session.getNamedQuery(queryName);
        HibernateTemplate.this.prepareQuery(queryObject);
        if (values != null) {
          for (int i = 0; i < values.length; i++) {
            HibernateTemplate.this.applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
          }
        }
        return queryObject.list();
      }
    });
  }
  
  public List findByNamedQueryAndValueBean(final String queryName, final Object valueBean)
    throws DataAccessException
  {
    (List)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Query queryObject = session.getNamedQuery(queryName);
        HibernateTemplate.this.prepareQuery(queryObject);
        queryObject.setProperties(valueBean);
        return queryObject.list();
      }
    });
  }
  
  public List findByCriteria(DetachedCriteria criteria)
    throws DataAccessException
  {
    return findByCriteria(criteria, -1, -1);
  }
  
  public List findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults)
    throws DataAccessException
  {
    Assert.notNull(criteria, "DetachedCriteria must not be null");
    (List)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Criteria executableCriteria = criteria.getExecutableCriteria(session);
        HibernateTemplate.this.prepareCriteria(executableCriteria);
        if (firstResult >= 0) {
          executableCriteria.setFirstResult(firstResult);
        }
        if (maxResults > 0) {
          executableCriteria.setMaxResults(maxResults);
        }
        return executableCriteria.list();
      }
    });
  }
  
  public List findByExample(Object exampleEntity)
    throws DataAccessException
  {
    return findByExample(null, exampleEntity, -1, -1);
  }
  
  public List findByExample(String entityName, Object exampleEntity)
    throws DataAccessException
  {
    return findByExample(entityName, exampleEntity, -1, -1);
  }
  
  public List findByExample(Object exampleEntity, int firstResult, int maxResults)
    throws DataAccessException
  {
    return findByExample(null, exampleEntity, firstResult, maxResults);
  }
  
  public List findByExample(final String entityName, final Object exampleEntity, final int firstResult, final int maxResults)
    throws DataAccessException
  {
    Assert.notNull(exampleEntity, "Example entity must not be null");
    (List)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Criteria executableCriteria = entityName != null ? session.createCriteria(entityName) : session.createCriteria(exampleEntity.getClass());
        
        executableCriteria.add(Example.create(exampleEntity));
        HibernateTemplate.this.prepareCriteria(executableCriteria);
        if (firstResult >= 0) {
          executableCriteria.setFirstResult(firstResult);
        }
        if (maxResults > 0) {
          executableCriteria.setMaxResults(maxResults);
        }
        return executableCriteria.list();
      }
    });
  }
  
  public Iterator iterate(String queryString)
    throws DataAccessException
  {
    return iterate(queryString, (Object[])null);
  }
  
  public Iterator iterate(String queryString, Object value)
    throws DataAccessException
  {
    return iterate(queryString, new Object[] { value });
  }
  
  public Iterator iterate(final String queryString, final Object[] values)
    throws DataAccessException
  {
    (Iterator)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Query queryObject = session.createQuery(queryString);
        HibernateTemplate.this.prepareQuery(queryObject);
        if (values != null) {
          for (int i = 0; i < values.length; i++) {
            queryObject.setParameter(i, values[i]);
          }
        }
        return queryObject.iterate();
      }
    });
  }
  
  public void closeIterator(Iterator it)
    throws DataAccessException
  {
    try
    {
      Hibernate.close(it);
    }
    catch (HibernateException ex)
    {
      throw SessionFactoryUtils.convertHibernateAccessException(ex);
    }
  }
  
  public int bulkUpdate(String queryString)
    throws DataAccessException
  {
    return bulkUpdate(queryString, (Object[])null);
  }
  
  public int bulkUpdate(String queryString, Object value)
    throws DataAccessException
  {
    return bulkUpdate(queryString, new Object[] { value });
  }
  
  public int bulkUpdate(final String queryString, final Object[] values)
    throws DataAccessException
  {
    Integer updateCount = (Integer)executeWithNativeSession(new HibernateCallback()
    {
      public Object doInHibernate(org.hibernate.Session session)
        throws HibernateException
      {
        Query queryObject = session.createQuery(queryString);
        HibernateTemplate.this.prepareQuery(queryObject);
        if (values != null) {
          for (int i = 0; i < values.length; i++) {
            queryObject.setParameter(i, values[i]);
          }
        }
        return new Integer(queryObject.executeUpdate());
      }
    });
    return updateCount.intValue();
  }
  
  protected void checkWriteOperationAllowed(org.hibernate.Session session)
    throws InvalidDataAccessApiUsageException
  {
    if ((isCheckWriteOperations()) && (getFlushMode() != 2) && (session.getFlushMode().lessThan(FlushMode.COMMIT))) {
      throw new InvalidDataAccessApiUsageException("Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.");
    }
  }
  
  protected void prepareQuery(Query queryObject)
  {
    if (isCacheQueries())
    {
      queryObject.setCacheable(true);
      if (getQueryCacheRegion() != null) {
        queryObject.setCacheRegion(getQueryCacheRegion());
      }
    }
    if (getFetchSize() > 0) {
      queryObject.setFetchSize(getFetchSize());
    }
    if (getMaxResults() > 0) {
      queryObject.setMaxResults(getMaxResults());
    }
    SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
  }
  
  protected void prepareCriteria(Criteria criteria)
  {
    if (isCacheQueries())
    {
      criteria.setCacheable(true);
      if (getQueryCacheRegion() != null) {
        criteria.setCacheRegion(getQueryCacheRegion());
      }
    }
    if (getFetchSize() > 0) {
      criteria.setFetchSize(getFetchSize());
    }
    if (getMaxResults() > 0) {
      criteria.setMaxResults(getMaxResults());
    }
    SessionFactoryUtils.applyTransactionTimeout(criteria, getSessionFactory());
  }
  
  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);
    }
  }
  
  private class CloseSuppressingInvocationHandler
    implements InvocationHandler
  {
    private final org.hibernate.Session target;
    
    public CloseSuppressingInvocationHandler(org.hibernate.Session target)
    {
      this.target = target;
    }
    
    public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable
    {
      if (method.getName().equals("equals")) {
        return proxy == args[0] ? Boolean.TRUE : Boolean.FALSE;
      }
      if (method.getName().equals("hashCode")) {
        return new Integer(System.identityHashCode(proxy));
      }
      if (method.getName().equals("close")) {
        return null;
      }
      try
      {
        Object retVal = method.invoke(this.target, args);
        if ((retVal instanceof Query)) {
          HibernateTemplate.this.prepareQuery((Query)retVal);
        }
        if ((retVal instanceof Criteria)) {
          HibernateTemplate.this.prepareCriteria((Criteria)retVal);
        }
        return retVal;
      }
      catch (InvocationTargetException ex)
      {
        throw ex.getTargetException();
      }
    }
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值