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.io.Serializable;
   28   import java.math.BigDecimal;
   29   import java.math.BigInteger;
   30   import java.util.ArrayList;
   31   import java.util.Arrays;
   32   import java.util.Calendar;
   33   import java.util.Collection;
   34   import java.util.Date;
   35   import java.util.HashMap;
   36   import java.util.HashSet;
   37   import java.util.Iterator;
   38   import java.util.List;
   39   import java.util.Locale;
   40   import java.util.Map;
   41   import java.util.Set;
   42   
   43   import org.hibernate.CacheMode;
   44   import org.hibernate.FlushMode;
   45   import org.hibernate.Hibernate;
   46   import org.hibernate.HibernateException;
   47   import org.hibernate.MappingException;
   48   import org.hibernate.NonUniqueResultException;
   49   import org.hibernate.PropertyNotFoundException;
   50   import org.hibernate.Query;
   51   import org.hibernate.QueryException;
   52   import org.hibernate.engine.QueryParameters;
   53   import org.hibernate.engine.RowSelection;
   54   import org.hibernate.engine.SessionImplementor;
   55   import org.hibernate.engine.TypedValue;
   56   import org.hibernate.engine.query.ParameterMetadata;
   57   import org.hibernate.hql.classic.ParserHelper;
   58   import org.hibernate.property.Getter;
   59   import org.hibernate.proxy.HibernateProxyHelper;
   60   import org.hibernate.transform.ResultTransformer;
   61   import org.hibernate.type.SerializableType;
   62   import org.hibernate.type.Type;
   63   import org.hibernate.type.TypeFactory;
   64   import org.hibernate.util.ArrayHelper;
   65   import org.hibernate.util.MarkerObject;
   66   import org.hibernate.util.ReflectHelper;
   67   import org.hibernate.util.StringHelper;
   68   
   69   /**
   70    * Abstract implementation of the Query interface.
   71    *
   72    * @author Gavin King
   73    * @author Max Andersen
   74    */
   75   public abstract class AbstractQueryImpl implements Query {
   76   
   77   	private static final Object UNSET_PARAMETER = new MarkerObject("<unset parameter>");
   78   	private static final Object UNSET_TYPE = new MarkerObject("<unset type>");
   79   
   80   	private final String queryString;
   81   	protected final SessionImplementor session;
   82   	protected final ParameterMetadata parameterMetadata;
   83   
   84   	// parameter bind values...
   85   	private List values = new ArrayList(4);
   86   	private List types = new ArrayList(4);
   87   	private Map namedParameters = new HashMap(4);
   88   	private Map namedParameterLists = new HashMap(4);
   89   
   90   	private Object optionalObject;
   91   	private Serializable optionalId;
   92   	private String optionalEntityName;
   93   
   94   	private RowSelection selection;
   95   	private boolean cacheable;
   96   	private String cacheRegion;
   97   	private String comment;
   98   	private FlushMode flushMode;
   99   	private CacheMode cacheMode;
  100   	private FlushMode sessionFlushMode;
  101   	private CacheMode sessionCacheMode;
  102   	private Serializable collectionKey;
  103   	private boolean readOnly;
  104   	private ResultTransformer resultTransformer;
  105   
  106   	public AbstractQueryImpl(
  107   			String queryString,
  108   	        FlushMode flushMode,
  109   	        SessionImplementor session,
  110   	        ParameterMetadata parameterMetadata) {
  111   		this.session = session;
  112   		this.queryString = queryString;
  113   		this.selection = new RowSelection();
  114   		this.flushMode = flushMode;
  115   		this.cacheMode = null;
  116   		this.parameterMetadata = parameterMetadata;
  117   	}
  118   
  119   	public String toString() {
  120   		return StringHelper.unqualify( getClass().getName() ) + '(' + queryString + ')';
  121   	}
  122   
  123   	public final String getQueryString() {
  124   		return queryString;
  125   	}
  126   
  127   	//TODO: maybe call it getRowSelection() ?
  128   	public RowSelection getSelection() {
  129   		return selection;
  130   	}
  131   	
  132   	public Query setFlushMode(FlushMode flushMode) {
  133   		this.flushMode = flushMode;
  134   		return this;
  135   	}
  136   	
  137   	public Query setCacheMode(CacheMode cacheMode) {
  138   		this.cacheMode = cacheMode;
  139   		return this;
  140   	}
  141   
  142   	public Query setCacheable(boolean cacheable) {
  143   		this.cacheable = cacheable;
  144   		return this;
  145   	}
  146   
  147   	public Query setCacheRegion(String cacheRegion) {
  148   		if (cacheRegion != null)
  149   			this.cacheRegion = cacheRegion.trim();
  150   		return this;
  151   	}
  152   
  153   	public Query setComment(String comment) {
  154   		this.comment = comment;
  155   		return this;
  156   	}
  157   
  158   	public Query setFirstResult(int firstResult) {
  159   		selection.setFirstRow( new Integer(firstResult) );
  160   		return this;
  161   	}
  162   
  163   	public Query setMaxResults(int maxResults) {
  164   		selection.setMaxRows( new Integer(maxResults) );
  165   		return this;
  166   	}
  167   
  168   	public Query setTimeout(int timeout) {
  169   		selection.setTimeout( new Integer(timeout) );
  170   		return this;
  171   	}
  172   	public Query setFetchSize(int fetchSize) {
  173   		selection.setFetchSize( new Integer(fetchSize) );
  174   		return this;
  175   	}
  176   
  177   	public Type[] getReturnTypes() throws HibernateException {
  178   		return session.getFactory().getReturnTypes( queryString );
  179   	}
  180   
  181   	public String[] getReturnAliases() throws HibernateException {
  182   		return session.getFactory().getReturnAliases( queryString );
  183   	}
  184   
  185   	public Query setCollectionKey(Serializable collectionKey) {
  186   		this.collectionKey = collectionKey;
  187   		return this;
  188   	}
  189   
  190   	public boolean isReadOnly() {
  191   		return readOnly;
  192   	}
  193   
  194   	public Query setReadOnly(boolean readOnly) {
  195   		this.readOnly = readOnly;
  196   		return this;
  197   	}
  198   
  199   	public Query setResultTransformer(ResultTransformer transformer) {
  200   		this.resultTransformer = transformer;
  201   		return this;
  202   	}
  203   	
  204   	public void setOptionalEntityName(String optionalEntityName) {
  205   		this.optionalEntityName = optionalEntityName;
  206   	}
  207   
  208   	public void setOptionalId(Serializable optionalId) {
  209   		this.optionalId = optionalId;
  210   	}
  211   
  212   	public void setOptionalObject(Object optionalObject) {
  213   		this.optionalObject = optionalObject;
  214   	}
  215   
  216   	SessionImplementor getSession() {
  217   		return session;
  218   	}
  219   
  220   	protected abstract Map getLockModes();
  221   
  222   
  223   	// Parameter handling code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  224   
  225   	/**
  226   	 * Returns a shallow copy of the named parameter value map.
  227   	 *
  228   	 * @return Shallow copy of the named parameter value map
  229   	 */
  230   	protected Map getNamedParams() {
  231   		return new HashMap( namedParameters );
  232   	}
  233   
  234   	/**
  235   	 * Returns an array representing all named parameter names encountered
  236   	 * during (intial) parsing of the query.
  237   	 * <p/>
  238   	 * Note <i>initial</i> here means different things depending on whether
  239   	 * this is a native-sql query or an HQL/filter query.  For native-sql, a
  240   	 * precursory inspection of the query string is performed specifically to
  241   	 * locate defined parameters.  For HQL/filter queries, this is the
  242   	 * information returned from the query-translator.  This distinction
  243   	 * holds true for all parameter metadata exposed here.
  244   	 *
  245   	 * @return Array of named parameter names.
  246   	 * @throws HibernateException
  247   	 */
  248   	public String[] getNamedParameters() throws HibernateException {
  249   		return ArrayHelper.toStringArray( parameterMetadata.getNamedParameterNames() );
  250   	}
  251   
  252   	/**
  253   	 * Does this query contain named parameters?
  254   	 *
  255   	 * @return True if the query was found to contain named parameters; false
  256   	 * otherwise;
  257   	 */
  258   	public boolean hasNamedParameters() {
  259   		return parameterMetadata.getNamedParameterNames().size() > 0;
  260   	}
  261   
  262   	/**
  263   	 * Retreive the value map for any named parameter lists (i.e., for
  264   	 * auto-expansion) bound to this query.
  265   	 *
  266   	 * @return The parameter list value map.
  267   	 */
  268   	protected Map getNamedParameterLists() {
  269   		return namedParameterLists;
  270   	}
  271   
  272   	/**
  273   	 * Retreives the list of parameter values bound to this query for
  274   	 * ordinal parameters.
  275   	 *
  276   	 * @return The ordinal parameter values.
  277   	 */
  278   	protected List getValues() {
  279   		return values;
  280   	}
  281   
  282   	/**
  283   	 * Retreives the list of parameter {@link Type type}s bound to this query for
  284   	 * ordinal parameters.
  285   	 *
  286   	 * @return The ordinal parameter types.
  287   	 */
  288   	protected List getTypes() {
  289   		return types;
  290   	}
  291   
  292   	/**
  293   	 * Perform parameter validation.  Used prior to executing the encapsulated
  294   	 * query.
  295   	 *
  296   	 * @throws QueryException
  297   	 */
  298   	protected void verifyParameters() throws QueryException {
  299   		verifyParameters(false);
  300   	}
  301   
  302   	/**
  303   	 * Perform parameter validation.  Used prior to executing the encapsulated
  304   	 * query.
  305   	 *
  306   	 * @param reserveFirstParameter if true, the first ? will not be verified since
  307   	 * its needed for e.g. callable statements returning a out parameter
  308   	 * @throws HibernateException
  309   	 */
  310   	protected void verifyParameters(boolean reserveFirstParameter) throws HibernateException {
  311   		if ( parameterMetadata.getNamedParameterNames().size() != namedParameters.size() + namedParameterLists.size() ) {
  312   			Set missingParams = new HashSet( parameterMetadata.getNamedParameterNames() );
  313   			missingParams.removeAll( namedParameterLists.keySet() );
  314   			missingParams.removeAll( namedParameters.keySet() );
  315   			throw new QueryException( "Not all named parameters have been set: " + missingParams, getQueryString() );
  316   		}
  317   
  318   		int positionalValueSpan = 0;
  319   		for ( int i = 0; i < values.size(); i++ ) {
  320   			Object object = types.get( i );
  321   			if( values.get( i ) == UNSET_PARAMETER || object == UNSET_TYPE ) {
  322   				if ( reserveFirstParameter && i==0 ) {
  323   					continue;
  324   				}
  325   				else {
  326   					throw new QueryException( "Unset positional parameter at position: " + i, getQueryString() );
  327   				}
  328   			}
  329   			positionalValueSpan += ( (Type) object ).getColumnSpan( session.getFactory() );
  330   		}
  331   
  332   		if ( parameterMetadata.getOrdinalParameterCount() != positionalValueSpan ) {
  333   			if ( reserveFirstParameter && parameterMetadata.getOrdinalParameterCount() - 1 != positionalValueSpan ) {
  334   				throw new QueryException(
  335   				 		"Expected positional parameter count: " +
  336   				 		(parameterMetadata.getOrdinalParameterCount()-1) +
  337   				 		", actual parameters: " +
  338   				 		values,
  339   				 		getQueryString()
  340   				 	);
  341   			}
  342   			else if ( !reserveFirstParameter ) {
  343   				throw new QueryException(
  344   				 		"Expected positional parameter count: " +
  345   				 		parameterMetadata.getOrdinalParameterCount() +
  346   				 		", actual parameters: " +
  347   				 		values,
  348   				 		getQueryString()
  349   				 	);
  350   			}
  351   		}
  352   	}
  353   
  354   	public Query setParameter(int position, Object val, Type type) {
  355   		if ( parameterMetadata.getOrdinalParameterCount() == 0 ) {
  356   			throw new IllegalArgumentException("No positional parameters in query: " + getQueryString() );
  357   		}
  358   		if ( position < 0 || position > parameterMetadata.getOrdinalParameterCount() - 1 ) {
  359   			throw new IllegalArgumentException("Positional parameter does not exist: " + position + " in query: " + getQueryString() );
  360   		}
  361   		int size = values.size();
  362   		if ( position < size ) {
  363   			values.set( position, val );
  364   			types.set( position, type );
  365   		}
  366   		else {
  367   			// prepend value and type list with null for any positions before the wanted position.
  368   			for ( int i = 0; i < position - size; i++ ) {
  369   				values.add( UNSET_PARAMETER );
  370   				types.add( UNSET_TYPE );
  371   			}
  372   			values.add( val );
  373   			types.add( type );
  374   		}
  375   		return this;
  376   	}
  377   
  378   	public Query setParameter(String name, Object val, Type type) {
  379   		if ( !parameterMetadata.getNamedParameterNames().contains( name ) ) {
  380   			throw new IllegalArgumentException("Parameter " + name + " does not exist as a named parameter in [" + getQueryString() + "]");
  381   		}
  382   		else {
  383   			 namedParameters.put( name, new TypedValue( type, val, session.getEntityMode() ) );
  384   			 return this;
  385   		}
  386   	}
  387   
  388   	public Query setParameter(int position, Object val) throws HibernateException {
  389   		if (val == null) {
  390   			setParameter( position, val, Hibernate.SERIALIZABLE );
  391   		}
  392   		else {
  393   			setParameter( position, val, determineType( position, val ) );
  394   		}
  395   		return this;
  396   	}
  397   
  398   	public Query setParameter(String name, Object val) throws HibernateException {
  399   		if (val == null) {
  400   			Type type = parameterMetadata.getNamedParameterExpectedType( name );
  401   			if ( type == null ) {
  402   				type = Hibernate.SERIALIZABLE;
  403   			}
  404   			setParameter( name, val, type );
  405   		}
  406   		else {
  407   			setParameter( name, val, determineType( name, val ) );
  408   		}
  409   		return this;
  410   	}
  411   
  412   	protected Type determineType(int paramPosition, Object paramValue, Type defaultType) {
  413   		Type type = parameterMetadata.getOrdinalParameterExpectedType( paramPosition + 1 );
  414   		if ( type == null ) {
  415   			type = defaultType;
  416   		}
  417   		return type;
  418   	}
  419   
  420   	protected Type determineType(int paramPosition, Object paramValue) throws HibernateException {
  421   		Type type = parameterMetadata.getOrdinalParameterExpectedType( paramPosition + 1 );
  422   		if ( type == null ) {
  423   			type = guessType( paramValue );
  424   		}
  425   		return type;
  426   	}
  427   
  428   	protected Type determineType(String paramName, Object paramValue, Type defaultType) {
  429   		Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
  430   		if ( type == null ) {
  431   			type = defaultType;
  432   		}
  433   		return type;
  434   	}
  435   
  436   	protected Type determineType(String paramName, Object paramValue) throws HibernateException {
  437   		Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
  438   		if ( type == null ) {
  439   			type = guessType( paramValue );
  440   		}
  441   		return type;
  442   	}
  443   
  444   	protected Type determineType(String paramName, Class clazz) throws HibernateException {
  445   		Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
  446   		if ( type == null ) {
  447   			type = guessType( clazz );
  448   		}
  449   		return type;
  450   	}
  451   
  452   	private Type guessType(Object param) throws HibernateException {
  453   		Class clazz = HibernateProxyHelper.getClassWithoutInitializingProxy( param );
  454   		return guessType( clazz );
  455   	}
  456   
  457   	private Type guessType(Class clazz) throws HibernateException {
  458   		String typename = clazz.getName();
  459   		Type type = TypeFactory.heuristicType(typename);
  460   		boolean serializable = type!=null && type instanceof SerializableType;
  461   		if (type==null || serializable) {
  462   			try {
  463   				session.getFactory().getEntityPersister( clazz.getName() );
  464   			}
  465   			catch (MappingException me) {
  466   				if (serializable) {
  467   					return type;
  468   				}
  469   				else {
  470   					throw new HibernateException("Could not determine a type for class: " + typename);
  471   				}
  472   			}
  473   			return Hibernate.entity(clazz);
  474   		}
  475   		else {
  476   			return type;
  477   		}
  478   	}
  479   
  480   	public Query setString(int position, String val) {
  481   		setParameter(position, val, Hibernate.STRING);
  482   		return this;
  483   	}
  484   
  485   	public Query setCharacter(int position, char val) {
  486   		setParameter(position, new Character(val), Hibernate.CHARACTER);
  487   		return this;
  488   	}
  489   
  490   	public Query setBoolean(int position, boolean val) {
  491   		Boolean valueToUse = val ? Boolean.TRUE : Boolean.FALSE;
  492   		Type typeToUse = determineType( position, valueToUse, Hibernate.BOOLEAN );
  493   		setParameter( position, valueToUse, typeToUse );
  494   		return this;
  495   	}
  496   
  497   	public Query setByte(int position, byte val) {
  498   		setParameter(position, new Byte(val), Hibernate.BYTE);
  499   		return this;
  500   	}
  501   
  502   	public Query setShort(int position, short val) {
  503   		setParameter(position, new Short(val), Hibernate.SHORT);
  504   		return this;
  505   	}
  506   
  507   	public Query setInteger(int position, int val) {
  508   		setParameter(position, new Integer(val), Hibernate.INTEGER);
  509   		return this;
  510   	}
  511   
  512   	public Query setLong(int position, long val) {
  513   		setParameter(position, new Long(val), Hibernate.LONG);
  514   		return this;
  515   	}
  516   
  517   	public Query setFloat(int position, float val) {
  518   		setParameter(position, new Float(val), Hibernate.FLOAT);
  519   		return this;
  520   	}
  521   
  522   	public Query setDouble(int position, double val) {
  523   		setParameter(position, new Double(val), Hibernate.DOUBLE);
  524   		return this;
  525   	}
  526   
  527   	public Query setBinary(int position, byte[] val) {
  528   		setParameter(position, val, Hibernate.BINARY);
  529   		return this;
  530   	}
  531   
  532   	public Query setText(int position, String val) {
  533   		setParameter(position, val, Hibernate.TEXT);
  534   		return this;
  535   	}
  536   
  537   	public Query setSerializable(int position, Serializable val) {
  538   		setParameter(position, val, Hibernate.SERIALIZABLE);
  539   		return this;
  540   	}
  541   
  542   	public Query setDate(int position, Date date) {
  543   		setParameter(position, date, Hibernate.DATE);
  544   		return this;
  545   	}
  546   
  547   	public Query setTime(int position, Date date) {
  548   		setParameter(position, date, Hibernate.TIME);
  549   		return this;
  550   	}
  551   
  552   	public Query setTimestamp(int position, Date date) {
  553   		setParameter(position, date, Hibernate.TIMESTAMP);
  554   		return this;
  555   	}
  556   
  557   	public Query setEntity(int position, Object val) {
  558   		setParameter( position, val, Hibernate.entity( resolveEntityName( val ) ) );
  559   		return this;
  560   	}
  561   
  562   	private String resolveEntityName(Object val) {
  563   		if ( val == null ) {
  564   			throw new IllegalArgumentException( "entity for parameter binding cannot be null" );
  565   		}
  566   		return session.bestGuessEntityName( val );
  567   	}
  568   
  569   	public Query setLocale(int position, Locale locale) {
  570   		setParameter(position, locale, Hibernate.LOCALE);
  571   		return this;
  572   	}
  573   
  574   	public Query setCalendar(int position, Calendar calendar) {
  575   		setParameter(position, calendar, Hibernate.CALENDAR);
  576   		return this;
  577   	}
  578   
  579   	public Query setCalendarDate(int position, Calendar calendar) {
  580   		setParameter(position, calendar, Hibernate.CALENDAR_DATE);
  581   		return this;
  582   	}
  583   
  584   	public Query setBinary(String name, byte[] val) {
  585   		setParameter(name, val, Hibernate.BINARY);
  586   		return this;
  587   	}
  588   
  589   	public Query setText(String name, String val) {
  590   		setParameter(name, val, Hibernate.TEXT);
  591   		return this;
  592   	}
  593   
  594   	public Query setBoolean(String name, boolean val) {
  595   		Boolean valueToUse = val ? Boolean.TRUE : Boolean.FALSE;
  596   		Type typeToUse = determineType( name, valueToUse, Hibernate.BOOLEAN );
  597   		setParameter( name, valueToUse, typeToUse );
  598   		return this;
  599   	}
  600   
  601   	public Query setByte(String name, byte val) {
  602   		setParameter(name, new Byte(val), Hibernate.BYTE);
  603   		return this;
  604   	}
  605   
  606   	public Query setCharacter(String name, char val) {
  607   		setParameter(name, new Character(val), Hibernate.CHARACTER);
  608   		return this;
  609   	}
  610   
  611   	public Query setDate(String name, Date date) {
  612   		setParameter(name, date, Hibernate.DATE);
  613   		return this;
  614   	}
  615   
  616   	public Query setDouble(String name, double val) {
  617   		setParameter(name, new Double(val), Hibernate.DOUBLE);
  618   		return this;
  619   	}
  620   
  621   	public Query setEntity(String name, Object val) {
  622   		setParameter( name, val, Hibernate.entity( resolveEntityName( val ) ) );
  623   		return this;
  624   	}
  625   
  626   	public Query setFloat(String name, float val) {
  627   		setParameter(name, new Float(val), Hibernate.FLOAT);
  628   		return this;
  629   	}
  630   
  631   	public Query setInteger(String name, int val) {
  632   		setParameter(name, new Integer(val), Hibernate.INTEGER);
  633   		return this;
  634   	}
  635   
  636   	public Query setLocale(String name, Locale locale) {
  637   		setParameter(name, locale, Hibernate.LOCALE);
  638   		return this;
  639   	}
  640   
  641   	public Query setCalendar(String name, Calendar calendar) {
  642   		setParameter(name, calendar, Hibernate.CALENDAR);
  643   		return this;
  644   	}
  645   
  646   	public Query setCalendarDate(String name, Calendar calendar) {
  647   		setParameter(name, calendar, Hibernate.CALENDAR_DATE);
  648   		return this;
  649   	}
  650   
  651   	public Query setLong(String name, long val) {
  652   		setParameter(name, new Long(val), Hibernate.LONG);
  653   		return this;
  654   	}
  655   
  656   	public Query setSerializable(String name, Serializable val) {
  657   		setParameter(name, val, Hibernate.SERIALIZABLE);
  658   		return this;
  659   	}
  660   
  661   	public Query setShort(String name, short val) {
  662   		setParameter(name, new Short(val), Hibernate.SHORT);
  663   		return this;
  664   	}
  665   
  666   	public Query setString(String name, String val) {
  667   		setParameter(name, val, Hibernate.STRING);
  668   		return this;
  669   	}
  670   
  671   	public Query setTime(String name, Date date) {
  672   		setParameter(name, date, Hibernate.TIME);
  673   		return this;
  674   	}
  675   
  676   	public Query setTimestamp(String name, Date date) {
  677   		setParameter(name, date, Hibernate.TIMESTAMP);
  678   		return this;
  679   	}
  680   
  681   	public Query setBigDecimal(int position, BigDecimal number) {
  682   		setParameter(position, number, Hibernate.BIG_DECIMAL);
  683   		return this;
  684   	}
  685   
  686   	public Query setBigDecimal(String name, BigDecimal number) {
  687   		setParameter(name, number, Hibernate.BIG_DECIMAL);
  688   		return this;
  689   	}
  690   
  691   	public Query setBigInteger(int position, BigInteger number) {
  692   		setParameter(position, number, Hibernate.BIG_INTEGER);
  693   		return this;
  694   	}
  695   
  696   	public Query setBigInteger(String name, BigInteger number) {
  697   		setParameter(name, number, Hibernate.BIG_INTEGER);
  698   		return this;
  699   	}
  700   
  701   	public Query setParameterList(String name, Collection vals, Type type) throws HibernateException {
  702   		if ( !parameterMetadata.getNamedParameterNames().contains( name ) ) {
  703   			throw new IllegalArgumentException("Parameter " + name + " does not exist as a named parameter in [" + getQueryString() + "]");
  704   		}
  705   		namedParameterLists.put( name, new TypedValue( type, vals, session.getEntityMode() ) );
  706   		return this;
  707   	}
  708   	
  709   	/**
  710   	 * Warning: adds new parameters to the argument by side-effect, as well as
  711   	 * mutating the query string!
  712   	 */
  713   	protected String expandParameterLists(Map namedParamsCopy) {
  714   		String query = this.queryString;
  715   		Iterator iter = namedParameterLists.entrySet().iterator();
  716   		while ( iter.hasNext() ) {
  717   			Map.Entry me = (Map.Entry) iter.next();
  718   			query = expandParameterList( query, (String) me.getKey(), (TypedValue) me.getValue(), namedParamsCopy );
  719   		}
  720   		return query;
  721   	}
  722   
  723   	/**
  724   	 * Warning: adds new parameters to the argument by side-effect, as well as
  725   	 * mutating the query string!
  726   	 */
  727   	private String expandParameterList(String query, String name, TypedValue typedList, Map namedParamsCopy) {
  728   		Collection vals = (Collection) typedList.getValue();
  729   		Type type = typedList.getType();
  730   		if ( vals.size() == 1 ) {
  731   			// short-circuit for performance...
  732   			namedParamsCopy.put( name, new TypedValue( type, vals.iterator().next(), session.getEntityMode() ) );
  733   			return query;
  734   		}
  735   
  736   		StringBuffer list = new StringBuffer( 16 );
  737   		Iterator iter = vals.iterator();
  738   		int i = 0;
  739   		boolean isJpaPositionalParam = parameterMetadata.getNamedParameterDescriptor( name ).isJpaStyle();
  740   		while ( iter.hasNext() ) {
  741   			String alias = ( isJpaPositionalParam ? 'x' + name : name ) + i++ + '_';
  742   			namedParamsCopy.put( alias, new TypedValue( type, iter.next(), session.getEntityMode() ) );
  743   			list.append( ParserHelper.HQL_VARIABLE_PREFIX ).append( alias );
  744   			if ( iter.hasNext() ) {
  745   				list.append( ", " );
  746   			}
  747   		}
  748   		String paramPrefix = isJpaPositionalParam ? "?" : ParserHelper.HQL_VARIABLE_PREFIX;
  749   		return StringHelper.replace( query, paramPrefix + name, list.toString(), true );
  750   	}
  751   
  752   	public Query setParameterList(String name, Collection vals) throws HibernateException {
  753   		if ( vals == null ) {
  754   			throw new QueryException( "Collection must be not null!" );
  755   		}
  756   
  757   		if( vals.size() == 0 ) {
  758   			setParameterList( name, vals, null );
  759   		}
  760   		else {
  761   			setParameterList(name, vals, determineType( name, vals.iterator().next() ) );
  762   		}
  763   
  764   		return this;
  765   	}
  766   
  767   	public Query setParameterList(String name, Object[] vals, Type type) throws HibernateException {
  768   		return setParameterList( name, Arrays.asList(vals), type );
  769   	}
  770   
  771   	public Query setParameterList(String name, Object[] vals) throws HibernateException {
  772   		return setParameterList( name, Arrays.asList(vals) );
  773   	}
  774   
  775   	public Query setProperties(Map map) throws HibernateException {
  776   		String[] params = getNamedParameters();
  777   		for (int i = 0; i < params.length; i++) {
  778   			String namedParam = params[i];
  779   				final Object object = map.get(namedParam);
  780   				if(object==null) {
  781   					continue;
  782   				}
  783   				Class retType = object.getClass();
  784   				if ( Collection.class.isAssignableFrom( retType ) ) {
  785   					setParameterList( namedParam, ( Collection ) object );
  786   				}
  787   				else if ( retType.isArray() ) {
  788   					setParameterList( namedParam, ( Object[] ) object );
  789   				}
  790   				else {
  791   					setParameter( namedParam, object, determineType( namedParam, retType ) );
  792   				}
  793   
  794   			
  795   		}
  796   		return this;				
  797   	}
  798   	
  799   	public Query setProperties(Object bean) throws HibernateException {
  800   		Class clazz = bean.getClass();
  801   		String[] params = getNamedParameters();
  802   		for (int i = 0; i < params.length; i++) {
  803   			String namedParam = params[i];
  804   			try {
  805   				Getter getter = ReflectHelper.getGetter( clazz, namedParam );
  806   				Class retType = getter.getReturnType();
  807   				final Object object = getter.get( bean );
  808   				if ( Collection.class.isAssignableFrom( retType ) ) {
  809   					setParameterList( namedParam, ( Collection ) object );
  810   				}
  811   				else if ( retType.isArray() ) {
  812   				 	setParameterList( namedParam, ( Object[] ) object );
  813   				}
  814   				else {
  815   					setParameter( namedParam, object, determineType( namedParam, retType ) );
  816   				}
  817   			}
  818   			catch (PropertyNotFoundException pnfe) {
  819   				// ignore
  820   			}
  821   		}
  822   		return this;
  823   	}
  824   
  825   	public Query setParameters(Object[] values, Type[] types) {
  826   		this.values = Arrays.asList(values);
  827   		this.types = Arrays.asList(types);
  828   		return this;
  829   	}
  830   
  831   
  832   	// Execution methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  833   
  834   	public Object uniqueResult() throws HibernateException {
  835   		return uniqueElement( list() );
  836   	}
  837   
  838   	static Object uniqueElement(List list) throws NonUniqueResultException {
  839   		int size = list.size();
  840   		if (size==0) return null;
  841   		Object first = list.get(0);
  842   		for ( int i=1; i<size; i++ ) {
  843   			if ( list.get(i)!=first ) {
  844   				throw new NonUniqueResultException( list.size() );
  845   			}
  846   		}
  847   		return first;
  848   	}
  849   
  850   	protected RowSelection getRowSelection() {
  851   		return selection;
  852   	}
  853   
  854   	public Type[] typeArray() {
  855   		return ArrayHelper.toTypeArray( getTypes() );
  856   	}
  857   	
  858   	public Object[] valueArray() {
  859   		return getValues().toArray();
  860   	}
  861   
  862   	public QueryParameters getQueryParameters(Map namedParams) {
  863   		return new QueryParameters(
  864   				typeArray(),
  865   				valueArray(),
  866   				namedParams,
  867   				getLockModes(),
  868   				getSelection(),
  869   				readOnly,
  870   				cacheable,
  871   				cacheRegion,
  872   				comment,
  873   				collectionKey == null ? null : new Serializable[] { collectionKey },
  874   				optionalObject,
  875   				optionalEntityName,
  876   				optionalId,
  877   				resultTransformer
  878   		);
  879   	}
  880   	
  881   	protected void before() {
  882   		if ( flushMode!=null ) {
  883   			sessionFlushMode = getSession().getFlushMode();
  884   			getSession().setFlushMode(flushMode);
  885   		}
  886   		if ( cacheMode!=null ) {
  887   			sessionCacheMode = getSession().getCacheMode();
  888   			getSession().setCacheMode(cacheMode);
  889   		}
  890   	}
  891   	
  892   	protected void after() {
  893   		if (sessionFlushMode!=null) {
  894   			getSession().setFlushMode(sessionFlushMode);
  895   			sessionFlushMode = null;
  896   		}
  897   		if (sessionCacheMode!=null) {
  898   			getSession().setCacheMode(sessionCacheMode);
  899   			sessionCacheMode = null;
  900   		}
  901   	}
  902   }

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