Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » impl » [javadoc | source]
    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.impl;
   26   
   27   import java.util.ArrayList;
   28   import java.util.Arrays;
   29   import java.util.Collection;
   30   import java.util.Iterator;
   31   import java.util.List;
   32   import java.util.Map;
   33   import java.io.Serializable;
   34   
   35   import org.hibernate.FlushMode;
   36   import org.hibernate.HibernateException;
   37   import org.hibernate.LockMode;
   38   import org.hibernate.Query;
   39   import org.hibernate.QueryException;
   40   import org.hibernate.SQLQuery;
   41   import org.hibernate.ScrollMode;
   42   import org.hibernate.ScrollableResults;
   43   import org.hibernate.MappingException;
   44   import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
   45   import org.hibernate.engine.ResultSetMappingDefinition;
   46   import org.hibernate.engine.NamedSQLQueryDefinition;
   47   import org.hibernate.engine.QueryParameters;
   48   import org.hibernate.engine.SessionImplementor;
   49   import org.hibernate.engine.query.ParameterMetadata;
   50   import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn;
   51   import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn;
   52   import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
   53   import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
   54   import org.hibernate.type.Type;
   55   import org.hibernate.util.CollectionHelper;
   56   import org.hibernate.util.StringHelper;
   57   
   58   /**
   59    * Implements SQL query passthrough.
   60    *
   61    * <pre>
   62    * <sql-query name="mySqlQuery">
   63    * <return alias="person" class="eg.Person"/>
   64    *   SELECT {person}.NAME AS {person.name}, {person}.AGE AS {person.age}, {person}.SEX AS {person.sex}
   65    *   FROM PERSON {person} WHERE {person}.NAME LIKE 'Hiber%'
   66    * </sql-query>
   67    * </pre>
   68    *
   69    * @author Max Andersen
   70    */
   71   public class SQLQueryImpl extends AbstractQueryImpl implements SQLQuery {
   72   
   73   	private final List queryReturns;
   74   	private Collection querySpaces;
   75   	private final boolean callable;
   76   	private boolean autodiscovertypes;
   77   
   78   	/**
   79   	 * Constructs a SQLQueryImpl given a sql query defined in the mappings.
   80   	 *
   81   	 * @param queryDef The representation of the defined <sql-query/>.
   82   	 * @param session The session to which this SQLQueryImpl belongs.
   83   	 * @param parameterMetadata Metadata about parameters found in the query.
   84   	 */
   85   	SQLQueryImpl(NamedSQLQueryDefinition queryDef, SessionImplementor session, ParameterMetadata parameterMetadata) {
   86   		super( queryDef.getQueryString(), queryDef.getFlushMode(), session, parameterMetadata );
   87   		if ( queryDef.getResultSetRef() != null ) {
   88   			ResultSetMappingDefinition definition = session.getFactory()
   89   					.getResultSetMapping( queryDef.getResultSetRef() );
   90   			if (definition == null) {
   91   				throw new MappingException(
   92   						"Unable to find resultset-ref definition: " +
   93   						queryDef.getResultSetRef()
   94   					);
   95   			}
   96   			this.queryReturns = Arrays.asList( definition.getQueryReturns() );
   97   		}
   98   		else {
   99   			this.queryReturns = Arrays.asList( queryDef.getQueryReturns() );
  100   		}
  101   
  102   		this.querySpaces = queryDef.getQuerySpaces();
  103   		this.callable = queryDef.isCallable();
  104   	}
  105   
  106   	SQLQueryImpl(
  107   			final String sql,
  108   	        final List queryReturns,
  109   	        final Collection querySpaces,
  110   	        final FlushMode flushMode,
  111   	        boolean callable,
  112   	        final SessionImplementor session,
  113   	        ParameterMetadata parameterMetadata) {
  114   		// TODO : absolutely no usages of this constructor form; can it go away?
  115   		super( sql, flushMode, session, parameterMetadata );
  116   		this.queryReturns = queryReturns;
  117   		this.querySpaces = querySpaces;
  118   		this.callable = callable;
  119   	}
  120   
  121   	SQLQueryImpl(
  122   			final String sql,
  123   	        final String returnAliases[],
  124   	        final Class returnClasses[],
  125   	        final LockMode[] lockModes,
  126   	        final SessionImplementor session,
  127   	        final Collection querySpaces,
  128   	        final FlushMode flushMode,
  129   	        ParameterMetadata parameterMetadata) {
  130   		// TODO : this constructor form is *only* used from constructor directly below us; can it go away?
  131   		super( sql, flushMode, session, parameterMetadata );
  132   		queryReturns = new ArrayList(returnAliases.length);
  133   		for ( int i=0; i<returnAliases.length; i++ ) {
  134   			NativeSQLQueryRootReturn ret = new NativeSQLQueryRootReturn(
  135   					returnAliases[i],
  136   					returnClasses[i].getName(),
  137   					lockModes==null ? LockMode.NONE : lockModes[i]
  138   			);
  139   			queryReturns.add(ret);
  140   		}
  141   		this.querySpaces = querySpaces;
  142   		this.callable = false;
  143   	}
  144   
  145   	SQLQueryImpl(
  146   			final String sql,
  147   	        final String returnAliases[],
  148   	        final Class returnClasses[],
  149   	        final SessionImplementor session,
  150   	        ParameterMetadata parameterMetadata) {
  151   		this( sql, returnAliases, returnClasses, null, session, null, null, parameterMetadata );
  152   	}
  153   
  154   	SQLQueryImpl(String sql, SessionImplementor session, ParameterMetadata parameterMetadata) {
  155   		super( sql, null, session, parameterMetadata );
  156   		queryReturns = new ArrayList();
  157   		querySpaces = null;
  158   		callable = false;
  159   	}
  160   
  161   	private static final NativeSQLQueryReturn[] NO_SQL_RETURNS = new NativeSQLQueryReturn[0];
  162   
  163   	private NativeSQLQueryReturn[] getQueryReturns() {
  164   		return ( NativeSQLQueryReturn[] ) queryReturns.toArray( NO_SQL_RETURNS );
  165   	}
  166   
  167   	public List list() throws HibernateException {
  168   		verifyParameters();
  169   		before();
  170   
  171   		Map namedParams = getNamedParams();
  172   		NativeSQLQuerySpecification spec = generateQuerySpecification( namedParams );
  173   
  174   		try {
  175   			return getSession().list( spec, getQueryParameters( namedParams ) );
  176   		}
  177   		finally {
  178   			after();
  179   		}
  180   	}
  181   
  182   	private NativeSQLQuerySpecification generateQuerySpecification(Map namedParams) {
  183   		return new NativeSQLQuerySpecification(
  184   		        expandParameterLists(namedParams),
  185   		        getQueryReturns(),
  186   		        querySpaces
  187   		);
  188   	}
  189   
  190   	public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
  191   		verifyParameters();
  192   		before();
  193   
  194   		Map namedParams = getNamedParams();
  195   		NativeSQLQuerySpecification spec = generateQuerySpecification( namedParams );
  196   
  197   		QueryParameters qp = getQueryParameters( namedParams );
  198   		qp.setScrollMode( scrollMode );
  199   
  200   		try {
  201   			return getSession().scroll( spec, qp );
  202   		}
  203   		finally {
  204   			after();
  205   		}
  206   	}
  207   
  208   	public ScrollableResults scroll() throws HibernateException {
  209   		return scroll(ScrollMode.SCROLL_INSENSITIVE);
  210   	}
  211   
  212   	public Iterator iterate() throws HibernateException {
  213   		throw new UnsupportedOperationException("SQL queries do not currently support iteration");
  214   	}
  215   
  216   	public QueryParameters getQueryParameters(Map namedParams) {
  217   		QueryParameters qp = super.getQueryParameters(namedParams);
  218   		qp.setCallable(callable);
  219   		qp.setAutoDiscoverScalarTypes(autodiscovertypes);
  220   		return qp;
  221   	}
  222   
  223   	protected void verifyParameters() {
  224   		verifyParameters( callable );
  225   		boolean noReturns = queryReturns==null || queryReturns.isEmpty();
  226   		if ( noReturns ) {
  227   			this.autodiscovertypes = noReturns;
  228   		}
  229   		else {
  230   			Iterator itr = queryReturns.iterator();
  231   			while ( itr.hasNext() ) {
  232   				NativeSQLQueryReturn rtn = ( NativeSQLQueryReturn ) itr.next();
  233   				if ( rtn instanceof NativeSQLQueryScalarReturn ) {
  234   					NativeSQLQueryScalarReturn scalar = ( NativeSQLQueryScalarReturn ) rtn;
  235   					if ( scalar.getType() == null ) {
  236   						autodiscovertypes = true;
  237   						break;
  238   					}
  239   				}
  240   			}
  241   		}
  242   	}
  243   
  244   	public String[] getReturnAliases() throws HibernateException {
  245   		throw new UnsupportedOperationException("SQL queries do not currently support returning aliases");
  246   	}
  247   
  248   	public Type[] getReturnTypes() throws HibernateException {
  249   		throw new UnsupportedOperationException("not yet implemented for SQL queries");
  250   	}
  251   
  252   	public Query setLockMode(String alias, LockMode lockMode) {
  253   		throw new UnsupportedOperationException("cannot set the lock mode for a native SQL query");
  254   	}
  255   
  256   	protected Map getLockModes() {
  257   		//we never need to apply locks to the SQL
  258   		return CollectionHelper.EMPTY_MAP;
  259   	}
  260   
  261   	public SQLQuery addScalar(String columnAlias, Type type) {
  262   		queryReturns.add( new NativeSQLQueryScalarReturn( columnAlias, type ) );
  263   		return this;
  264   	}
  265   
  266   	public SQLQuery addScalar(String columnAlias) {
  267   		autodiscovertypes = true;
  268   		queryReturns.add( new NativeSQLQueryScalarReturn( columnAlias, null ) );
  269   		return this;
  270   	}
  271   
  272   	public SQLQuery addJoin(String alias, String path) {
  273   		return addJoin(alias, path, LockMode.READ);
  274   	}
  275   
  276   	public SQLQuery addEntity(Class entityClass) {
  277   		return addEntity( StringHelper.unqualify( entityClass.getName() ), entityClass );
  278   	}
  279   
  280   	public SQLQuery addEntity(String entityName) {
  281   		return addEntity( StringHelper.unqualify( entityName ), entityName );
  282   	}
  283   
  284   	public SQLQuery addEntity(String alias, String entityName) {
  285   		return addEntity(alias, entityName, LockMode.READ);
  286   	}
  287   
  288   	public SQLQuery addEntity(String alias, Class entityClass) {
  289   		return addEntity( alias, entityClass.getName() );
  290   	}
  291   
  292   	public SQLQuery addJoin(String alias, String path, LockMode lockMode) {
  293   		int loc = path.indexOf('.');
  294   		if ( loc < 0 ) {
  295   			throw new QueryException( "not a property path: " + path );
  296   		}
  297   		String ownerAlias = path.substring(0, loc);
  298   		String role = path.substring(loc+1);
  299   		queryReturns.add( new NativeSQLQueryJoinReturn(alias, ownerAlias, role, CollectionHelper.EMPTY_MAP, lockMode) );
  300   		return this;
  301   	}
  302   
  303   	public SQLQuery addEntity(String alias, String entityName, LockMode lockMode) {
  304   		queryReturns.add( new NativeSQLQueryRootReturn(alias, entityName, lockMode) );
  305   		return this;
  306   	}
  307   
  308   	public SQLQuery addEntity(String alias, Class entityClass, LockMode lockMode) {
  309   		return addEntity( alias, entityClass.getName(), lockMode );
  310   	}
  311   
  312   	public SQLQuery setResultSetMapping(String name) {
  313   		ResultSetMappingDefinition mapping = session.getFactory().getResultSetMapping( name );
  314   		if ( mapping == null ) {
  315   			throw new MappingException( "Unknown SqlResultSetMapping [" + name + "]" );
  316   		}
  317   		NativeSQLQueryReturn[] returns = mapping.getQueryReturns();
  318   		int length = returns.length;
  319   		for ( int index = 0 ; index < length ; index++ ) {
  320   			queryReturns.add( returns[index] );
  321   		}
  322   		return this;
  323   	}
  324   
  325   	public SQLQuery addSynchronizedQuerySpace(String querySpace) {
  326   		if ( querySpaces == null ) {
  327   			querySpaces = new ArrayList();
  328   		}
  329   		querySpaces.add( querySpace );
  330   		return this;
  331   	}
  332   
  333   	public SQLQuery addSynchronizedEntityName(String entityName) {
  334   		return addQuerySpaces( getSession().getFactory().getEntityPersister( entityName ).getQuerySpaces() );
  335   	}
  336   
  337   	public SQLQuery addSynchronizedEntityClass(Class entityClass) {
  338   		return addQuerySpaces( getSession().getFactory().getEntityPersister( entityClass.getName() ).getQuerySpaces() );
  339   	}
  340   
  341   	private SQLQuery addQuerySpaces(Serializable[] spaces) {
  342   		if ( spaces != null ) {
  343   			if ( querySpaces == null ) {
  344   				querySpaces = new ArrayList();
  345   			}
  346   			for ( int i = 0; i < spaces.length; i++ ) {
  347   				querySpaces.add( spaces[i] );
  348   			}
  349   		}
  350   		return this;
  351   	}
  352   
  353   	public int executeUpdate() throws HibernateException {
  354   		Map namedParams = getNamedParams();
  355   		before();
  356   		try {
  357   			return getSession().executeNativeUpdate(
  358   					generateQuerySpecification( namedParams ),
  359   					getQueryParameters( namedParams )
  360   			);
  361   		}
  362   		finally {
  363   			after();
  364   		}
  365   	}
  366   
  367   }

Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » impl » [javadoc | source]