[hibernate-commits] Hibernate SVN: r15240 - in core/branches/Branch_3_2: src/org/hibernate/engine and 8 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Oct 1 15:32:11 EDT 2008


Author: steve.ebersole at jboss.com
Date: 2008-10-01 15:32:11 -0400 (Wed, 01 Oct 2008)
New Revision: 15240

Added:
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/ParameterContainer.java
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Basic.hbm.xml
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/BasicFilteredBulkManipulationTest.java
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Customer.java
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Employee.java
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Joined.hbm.xml
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/JoinedFilteredBulkManipulationTest.java
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Person.java
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/User.java
   core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/filter-defs.hbm.xml
Modified:
   core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java
   core/branches/Branch_3_2/src/org/hibernate/engine/QueryParameters.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/HqlSqlWalker.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/QueryTranslatorImpl.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/SqlGenerator.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/BasicExecutor.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromElement.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/SqlFragment.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/JoinProcessor.java
   core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/SyntheticAndFactory.java
   core/branches/Branch_3_2/src/org/hibernate/loader/hql/QueryLoader.java
   core/branches/Branch_3_2/src/org/hibernate/param/CollectionFilterKeyParameterSpecification.java
   core/branches/Branch_3_2/src/org/hibernate/param/DynamicFilterParameterSpecification.java
   core/branches/Branch_3_2/src/org/hibernate/param/NamedParameterSpecification.java
   core/branches/Branch_3_2/src/org/hibernate/param/PositionalParameterSpecification.java
   core/branches/Branch_3_2/src/org/hibernate/param/VersionTypeSeedParameterSpecification.java
   core/branches/Branch_3_2/test/org/hibernate/test/filter/DynamicFilterTest.java
Log:
HHH-530 : filters + subqueries;
HHH-3506 : filters + HQL update/delete

Modified: core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -1,14 +1,13 @@
 //$Id$
 package org.hibernate.criterion;
 
-import java.util.HashMap;
-
 import org.hibernate.Criteria;
 import org.hibernate.EntityMode;
 import org.hibernate.HibernateException;
 import org.hibernate.engine.QueryParameters;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.engine.TypedValue;
+import org.hibernate.engine.SessionImplementor;
 import org.hibernate.impl.CriteriaImpl;
 import org.hibernate.loader.criteria.CriteriaJoinWalker;
 import org.hibernate.loader.criteria.CriteriaQueryTranslator;
@@ -19,7 +18,7 @@
  * @author Gavin King
  */
 public abstract class SubqueryExpression implements Criterion {
-	
+
 	private CriteriaImpl criteriaImpl;
 	private String quantifier;
 	private String op;
@@ -30,49 +29,67 @@
 	protected Type[] getTypes() {
 		return types;
 	}
-	
+
 	protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc) {
 		this.criteriaImpl = dc.getCriteriaImpl();
 		this.quantifier = quantifier;
 		this.op = op;
 	}
-	
+
 	protected abstract String toLeftSqlString(Criteria criteria, CriteriaQuery outerQuery);
 
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
 		final SessionFactoryImplementor factory = criteriaQuery.getFactory();
-		final OuterJoinLoadable persister = (OuterJoinLoadable) factory.getEntityPersister( criteriaImpl.getEntityOrClassName() );
+		final OuterJoinLoadable persister =
+				( OuterJoinLoadable ) factory.getEntityPersister( criteriaImpl.getEntityOrClassName() );
 
 		createAndSetInnerQuery( criteriaQuery, factory );
-		
+		criteriaImpl.setSession( deriveRootSession( criteria ) );
+
 		CriteriaJoinWalker walker = new CriteriaJoinWalker(
 				persister,
 				innerQuery,
 				factory,
 				criteriaImpl,
 				criteriaImpl.getEntityOrClassName(),
-				new HashMap(),
-				innerQuery.getRootSQLALias());
+				criteriaImpl.getSession().getEnabledFilters(),
+				innerQuery.getRootSQLALias()
+		);
 
 		String sql = walker.getSQLString();
 
-		final StringBuffer buf = new StringBuffer()
-			.append( toLeftSqlString(criteria, criteriaQuery) );
-		if (op!=null) buf.append(' ').append(op).append(' ');
-		if (quantifier!=null) buf.append(quantifier).append(' ');
-		return buf.append('(').append(sql).append(')')
-			.toString();
+		final StringBuffer buf = new StringBuffer( toLeftSqlString(criteria, criteriaQuery) );
+		if ( op != null ) {
+			buf.append( ' ' ).append( op ).append( ' ' );
+		}
+		if ( quantifier != null ) {
+			buf.append( quantifier ).append( ' ' );
+		}
+		return buf.append( '(' ).append( sql ).append( ')' )
+				.toString();
 	}
 
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
+	private SessionImplementor deriveRootSession(Criteria criteria) {
+		if ( criteria instanceof CriteriaImpl ) {
+			return ( ( CriteriaImpl ) criteria ).getSession();
+		}
+		else if ( criteria instanceof CriteriaImpl.Subcriteria ) {
+			return deriveRootSession( ( ( CriteriaImpl.Subcriteria ) criteria ).getParent() );
+		}
+		else {
+			// could happen for custom Criteria impls.  Not likely, but...
+			// 		for long term solution, see HHH-3514
+			return null;
+		}
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
 	throws HibernateException {
 		//the following two lines were added to ensure that this.params is not null, which
 		//can happen with two-deep nested subqueries
 		SessionFactoryImplementor factory = criteriaQuery.getFactory();
 		createAndSetInnerQuery(criteriaQuery, factory);
-		
+
 		Type[] ppTypes = params.getPositionalParameterTypes();
 		Object[] ppValues = params.getPositionalParameterValues();
 		TypedValue[] tv = new TypedValue[ppTypes.length];
@@ -83,12 +100,12 @@
 	}
 
 	/**
-	 * Creates the inner query used to extract some useful information about
-	 * types, since it is needed in both methods.
-	 * @param criteriaQuery
-	 * @param factory
+	 * Creates the inner query used to extract some useful information about types, since it is needed in both methods.
+	 *
+	 * @param criteriaQuery The criteria query
+	 * @param factory The session factory.
 	 */
-	private void createAndSetInnerQuery(CriteriaQuery criteriaQuery, final SessionFactoryImplementor factory) {
+	private void createAndSetInnerQuery(CriteriaQuery criteriaQuery, SessionFactoryImplementor factory) {
 		if ( innerQuery == null ) {
 			//with two-deep subqueries, the same alias would get generated for
 			//both using the old method (criteriaQuery.generateSQLAlias()), so

Modified: core/branches/Branch_3_2/src/org/hibernate/engine/QueryParameters.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/engine/QueryParameters.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/engine/QueryParameters.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -3,7 +3,6 @@
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
@@ -16,6 +15,7 @@
 import org.hibernate.HibernateException;
 import org.hibernate.QueryException;
 import org.hibernate.ScrollMode;
+import org.hibernate.impl.FilterImpl;
 import org.hibernate.dialect.Dialect;
 import org.hibernate.hql.classic.ParserHelper;
 import org.hibernate.pretty.Printer;
@@ -46,29 +46,28 @@
 	private boolean callable = false;
 	private boolean autodiscovertypes = false;
 	private boolean isNaturalKeyLookup;
-	
+
 	private final ResultTransformer resultTransformer; // why is all others non final ?
-	
+
 	private String processedSQL;
 	private Type[] processedPositionalParameterTypes;
 	private Object[] processedPositionalParameterValues;
-	
+
 	public QueryParameters() {
 		this( ArrayHelper.EMPTY_TYPE_ARRAY, ArrayHelper.EMPTY_OBJECT_ARRAY );
 	}
 
 	public QueryParameters(Type type, Object value) {
-		this( new Type[] {type}, new Object[] {value} );
+		this( new Type[] { type }, new Object[] { value } );
 	}
 
 	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] postionalParameterValues,
-		final Object optionalObject,
-		final String optionalEntityName,
-		final Serializable optionalObjectId
-	) {
-		this(positionalParameterTypes, postionalParameterValues);
+			final Type[] positionalParameterTypes,
+			final Object[] postionalParameterValues,
+			final Object optionalObject,
+			final String optionalEntityName,
+			final Serializable optionalObjectId) {
+		this( positionalParameterTypes, postionalParameterValues );
 		this.optionalObject = optionalObject;
 		this.optionalId = optionalObjectId;
 		this.optionalEntityName = optionalEntityName;
@@ -76,42 +75,24 @@
 	}
 
 	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] postionalParameterValues
-	) {
-		this(
-			positionalParameterTypes,
-			postionalParameterValues, 
-			null, 
-			null, 
-			false, 
-			null, 
-			null,
-			false,
-			null
-		);
+			final Type[] positionalParameterTypes,
+			final Object[] postionalParameterValues) {
+		this( positionalParameterTypes, postionalParameterValues, null, null, false, null, null, false, null );
 	}
 
 	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] postionalParameterValues,
-		final Serializable[] collectionKeys
-	) {
-		this(
-			positionalParameterTypes,
-			postionalParameterValues,
-			null,
-			collectionKeys
-		);
+			final Type[] positionalParameterTypes,
+			final Object[] postionalParameterValues,
+			final Serializable[] collectionKeys) {
+		this( positionalParameterTypes, postionalParameterValues, null, collectionKeys );
 	}
 
 	public QueryParameters(
 			final Type[] positionalParameterTypes,
 			final Object[] postionalParameterValues,
 			final Map namedParameters,
-			final Serializable[] collectionKeys
-		) {
-			this(
+			final Serializable[] collectionKeys) {
+		this(
 				positionalParameterTypes,
 				postionalParameterValues,
 				namedParameters,
@@ -119,37 +100,36 @@
 				null,
 				false,
 				false,
-				null, 
 				null,
+				null,
 				collectionKeys,
 				null
-			);
-		}
+		);
+	}
 
 	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] positionalParameterValues,
-		final Map lockModes,
-		final RowSelection rowSelection,
-		final boolean cacheable,
-		final String cacheRegion,
-		//final boolean forceCacheRefresh,
-		final String comment,
-		final boolean isLookupByNaturalKey,
-		final ResultTransformer transformer
-	) {
+			final Type[] positionalParameterTypes,
+			final Object[] positionalParameterValues,
+			final Map lockModes,
+			final RowSelection rowSelection,
+			final boolean cacheable,
+			final String cacheRegion,
+			//final boolean forceCacheRefresh,
+			final String comment,
+			final boolean isLookupByNaturalKey,
+			final ResultTransformer transformer) {
 		this(
-			positionalParameterTypes,
-			positionalParameterValues,
-			null,
-			lockModes,
-			rowSelection,
-			false,
-			cacheable,
-			cacheRegion, 
-			comment,
-			null,
-			transformer
+				positionalParameterTypes,
+				positionalParameterValues,
+				null,
+				lockModes,
+				rowSelection,
+				false,
+				cacheable,
+				cacheRegion,
+				comment,
+				null,
+				transformer
 		);
 		isNaturalKeyLookup = isLookupByNaturalKey;
 	}
@@ -166,8 +146,7 @@
 			//final boolean forceCacheRefresh,
 			final String comment,
 			final Serializable[] collectionKeys,
-			ResultTransformer transformer			
-	) {
+			ResultTransformer transformer) {
 		this.positionalParameterTypes = positionalParameterTypes;
 		this.positionalParameterValues = positionalParameterValues;
 		this.namedParameters = namedParameters;
@@ -181,36 +160,35 @@
 		this.readOnly = readOnly;
 		this.resultTransformer = transformer;
 	}
-	
+
 	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] positionalParameterValues,
-		final Map namedParameters,
-		final Map lockModes,
-		final RowSelection rowSelection,
-		final boolean readOnly,
-		final boolean cacheable,
-		final String cacheRegion,
-		//final boolean forceCacheRefresh,
-		final String comment,
-		final Serializable[] collectionKeys,
-		final Object optionalObject,
-		final String optionalEntityName,
-		final Serializable optionalId,
-		final ResultTransformer transformer
-	) {
+			final Type[] positionalParameterTypes,
+			final Object[] positionalParameterValues,
+			final Map namedParameters,
+			final Map lockModes,
+			final RowSelection rowSelection,
+			final boolean readOnly,
+			final boolean cacheable,
+			final String cacheRegion,
+			//final boolean forceCacheRefresh,
+			final String comment,
+			final Serializable[] collectionKeys,
+			final Object optionalObject,
+			final String optionalEntityName,
+			final Serializable optionalId,
+			final ResultTransformer transformer) {
 		this(
-			positionalParameterTypes, 
-			positionalParameterValues, 
-			namedParameters, 
-			lockModes, 
-			rowSelection, 
-			readOnly, 
-			cacheable, 
-			cacheRegion,
-			comment,
-			collectionKeys,
-			transformer
+				positionalParameterTypes,
+				positionalParameterValues,
+				namedParameters,
+				lockModes,
+				rowSelection,
+				readOnly,
+				cacheable,
+				cacheRegion,
+				comment,
+				collectionKeys,
+				transformer
 		);
 		this.optionalEntityName = optionalEntityName;
 		this.optionalId = optionalId;
@@ -218,7 +196,7 @@
 	}
 
 	public boolean hasRowSelection() {
-		return rowSelection!=null;
+		return rowSelection != null;
 	}
 
 	public Map getNamedParameters() {
@@ -236,7 +214,7 @@
 	public RowSelection getRowSelection() {
 		return rowSelection;
 	}
-	
+
 	public ResultTransformer getResultTransformer() {
 		return resultTransformer;
 	}
@@ -266,15 +244,15 @@
 	}
 
 	public void traceParameters(SessionFactoryImplementor factory) throws HibernateException {
-		Printer print = new Printer(factory);
-		if (positionalParameterValues.length!=0) {
+		Printer print = new Printer( factory );
+		if ( positionalParameterValues.length != 0 ) {
 			log.trace(
-					"parameters: " + 
-					print.toString(positionalParameterTypes, positionalParameterValues) 
-				);
+					"parameters: " +
+							print.toString( positionalParameterTypes, positionalParameterValues )
+			);
 		}
-		if (namedParameters!=null) {
-			log.trace( "named parameters: " + print.toString(namedParameters) );
+		if ( namedParameters != null ) {
+			log.trace( "named parameters: " + print.toString( namedParameters ) );
 		}
 	}
 
@@ -295,13 +273,13 @@
 	}
 
 	public void validateParameters() throws QueryException {
-		int types = positionalParameterTypes==null ? 0 : positionalParameterTypes.length;
-		int values = positionalParameterValues==null ? 0 : positionalParameterValues.length;
-		if (types!=values) {
+		int types = positionalParameterTypes == null ? 0 : positionalParameterTypes.length;
+		int values = positionalParameterValues == null ? 0 : positionalParameterValues.length;
+		if ( types != values ) {
 			throw new QueryException(
-					"Number of positional parameter types:" + types + 
-					" does not match number of positional parameters: " + values
-				);
+					"Number of positional parameter types:" + types +
+							" does not match number of positional parameters: " + values
+			);
 		}
 	}
 
@@ -362,44 +340,49 @@
 	}
 
 	public void setCallable(boolean callable) {
-		this.callable = callable;		
+		this.callable = callable;
 	}
 
 	public boolean isCallable() {
 		return callable;
 	}
-	
+
 	public boolean hasAutoDiscoverScalarTypes() {
 		return autodiscovertypes;
 	}
 
 	public void processFilters(String sql, SessionImplementor session) {
-		
-		if ( session.getEnabledFilters().size()==0 || sql.indexOf(ParserHelper.HQL_VARIABLE_PREFIX)<0 ) {
+		processFilters( sql, session.getEnabledFilters(), session.getFactory() );
+	}
+
+	public void processFilters(String sql, Map filters, SessionFactoryImplementor factory) {
+		if ( filters.size() == 0 || sql.indexOf( ParserHelper.HQL_VARIABLE_PREFIX ) < 0 ) {
 			// HELLA IMPORTANT OPTIMIZATION!!!
 			processedPositionalParameterValues = getPositionalParameterValues();
 			processedPositionalParameterTypes = getPositionalParameterTypes();
 			processedSQL = sql;
 		}
 		else {
-			
-			Dialect dialect = session.getFactory().getDialect();
+			final Dialect dialect = factory.getDialect();
 			String symbols = new StringBuffer().append( ParserHelper.HQL_SEPARATORS )
 					.append( dialect.openQuote() )
 					.append( dialect.closeQuote() )
 					.toString();
 			StringTokenizer tokens = new StringTokenizer( sql, symbols, true );
 			StringBuffer result = new StringBuffer();
-		
+
 			List parameters = new ArrayList();
 			List parameterTypes = new ArrayList();
-		
+
+			int positionalIndex = 0;
 			while ( tokens.hasMoreTokens() ) {
 				final String token = tokens.nextToken();
 				if ( token.startsWith( ParserHelper.HQL_VARIABLE_PREFIX ) ) {
-					String filterParameterName = token.substring( 1 );
-					Object value = session.getFilterParameterValue( filterParameterName );
-					Type type = session.getFilterParameterType( filterParameterName );
+					final String filterParameterName = token.substring( 1 );
+					final String[] parts = parseFilterParameterName( filterParameterName );
+					final FilterImpl filter = ( FilterImpl ) filters.get( parts[0] );
+					final Object value = filter.getParameter( parts[1] );
+					final Type type = filter.getFilterDefinition().getParameterType( parts[1] );
 					if ( value != null && Collection.class.isAssignableFrom( value.getClass() ) ) {
 						Iterator itr = ( ( Collection ) value ).iterator();
 						while ( itr.hasNext() ) {
@@ -419,15 +402,17 @@
 					}
 				}
 				else {
+					if ( "?".equals( token ) && positionalIndex < getPositionalParameterValues().length ) {
+						parameters.add( getPositionalParameterValues()[positionalIndex] );
+						parameterTypes.add( getPositionalParameterTypes()[positionalIndex] );
+						positionalIndex++;
+					}
 					result.append( token );
 				}
 			}
-			parameters.addAll( Arrays.asList( getPositionalParameterValues() ) );
-			parameterTypes.addAll( Arrays.asList( getPositionalParameterTypes() ) );
 			processedPositionalParameterValues = parameters.toArray();
-			processedPositionalParameterTypes = ( Type[] ) parameterTypes.toArray( new Type[0] );
+			processedPositionalParameterTypes = ( Type[] ) parameterTypes.toArray( new Type[parameterTypes.size()] );
 			processedSQL = result.toString();
-			
 		}
 	}
 
@@ -458,16 +443,16 @@
 	public QueryParameters createCopyUsing(RowSelection selection) {
 		QueryParameters copy = new QueryParameters(
 				this.positionalParameterTypes,
-		        this.positionalParameterValues,
-		        this.namedParameters,
-		        this.lockModes,
-	            selection,
-		        this.readOnly,
-		        this.cacheable,
-	            this.cacheRegion,
-		        this.comment,
-		        this.collectionKeys,
-		        this.optionalObject,
+				this.positionalParameterValues,
+				this.namedParameters,
+				this.lockModes,
+				selection,
+				this.readOnly,
+				this.cacheable,
+				this.cacheRegion,
+				this.comment,
+				this.collectionKeys,
+				this.optionalObject,
 				this.optionalEntityName,
 				this.optionalId,
 				this.resultTransformer
@@ -478,5 +463,13 @@
 		return copy;
 	}
 
-	
+	public static String[] parseFilterParameterName(String filterParameterName) {
+		int dot = filterParameterName.indexOf( '.' );
+		if ( dot <= 0 ) {
+			throw new IllegalArgumentException( "Invalid filter-parameter name format" );
+		}
+		String filterName = filterParameterName.substring( 0, dot );
+		String parameterName = filterParameterName.substring( dot + 1 );
+		return new String[] { filterName, parameterName };
+	}
 }

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/HqlSqlWalker.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/HqlSqlWalker.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/HqlSqlWalker.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -209,6 +209,10 @@
 		return collectionFilterRole != null;
 	}
 
+	public String getCollectionFilterRole() {
+		return collectionFilterRole;
+	}
+
 	public SessionFactoryHelper getSessionFactoryHelper() {
 		return sessionFactoryHelper;
 	}
@@ -531,8 +535,8 @@
 
 			// After that, process the JOINs.
 			// Invoke a delegate to do the work, as this is farily complex.
-			JoinProcessor joinProcessor = new JoinProcessor( astFactory, queryTranslatorImpl );
-			joinProcessor.processJoins( qn, isSubQuery() );
+			JoinProcessor joinProcessor = new JoinProcessor( this );
+			joinProcessor.processJoins( qn );
 
 			// Attach any mapping-defined "ORDER BY" fragments
 			Iterator itr = qn.getFromClause().getProjectionList().iterator();
@@ -570,13 +574,21 @@
 		// Make #@%$^#^&# sure no alias is applied to the table name
 		fromElement.setText( persister.getTableName() );
 
-		// append any filter fragments; the EMPTY_MAP is used under the assumption that
-		// currently enabled filters should not affect this process
-		if ( persister.getDiscriminatorType() != null ) {
-			new SyntheticAndFactory( getASTFactory() ).addDiscriminatorWhereFragment(
+//		// append any filter fragments; the EMPTY_MAP is used under the assumption that
+//		// currently enabled filters should not affect this process
+//		if ( persister.getDiscriminatorType() != null ) {
+//			new SyntheticAndFactory( getASTFactory() ).addDiscriminatorWhereFragment(
+//			        statement,
+//			        persister,
+//			        java.util.Collections.EMPTY_MAP,
+//			        fromElement.getTableAlias()
+//			);
+//		}
+		if ( persister.getDiscriminatorType() != null || ! queryTranslatorImpl.getEnabledFilters().isEmpty() ) {
+			new SyntheticAndFactory( this ).addDiscriminatorWhereFragment(
 			        statement,
 			        persister,
-			        java.util.Collections.EMPTY_MAP,
+			        queryTranslatorImpl.getEnabledFilters(),
 			        fromElement.getTableAlias()
 			);
 		}

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/QueryTranslatorImpl.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/QueryTranslatorImpl.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/QueryTranslatorImpl.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -74,7 +74,9 @@
 	private String sql;
 
 	private ParameterTranslations paramTranslations;
+	private List collectedParameterSpecifications;
 
+
 	/**
 	 * Creates a new AST-based query translator.
 	 *
@@ -217,6 +219,7 @@
 				log.debug( "SQL: " + sql );
 			}
 			gen.getParseErrorHandler().throwQueryException();
+			collectedParameterSpecifications = gen.getCollectedParameters();
 		}
 	}
 
@@ -540,10 +543,15 @@
 	public ParameterTranslations getParameterTranslations() {
 		if ( paramTranslations == null ) {
 			paramTranslations = new ParameterTranslationsImpl( getWalker().getParameters() );
+//			paramTranslations = new ParameterTranslationsImpl( collectedParameterSpecifications );
 		}
 		return paramTranslations;
 	}
 
+	public List getCollectedParameterSpecifications() {
+		return collectedParameterSpecifications;
+	}
+
 	public static class JavaConstantConverter implements NodeTraverser.VisitationStrategy {
 		private AST dotRoot;
 		public void visit(AST node) {

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/SqlGenerator.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/SqlGenerator.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/SqlGenerator.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -4,16 +4,20 @@
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Arrays;
 
 import antlr.RecognitionException;
 import antlr.collections.AST;
 import org.hibernate.QueryException;
+import org.hibernate.param.ParameterSpecification;
 import org.hibernate.dialect.function.SQLFunction;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.hql.antlr.SqlGeneratorBase;
 import org.hibernate.hql.ast.tree.MethodNode;
 import org.hibernate.hql.ast.tree.FromElement;
 import org.hibernate.hql.ast.tree.Node;
+import org.hibernate.hql.ast.tree.ParameterNode;
+import org.hibernate.hql.ast.tree.ParameterContainer;
 
 /**
  * Generates SQL by overriding callback methods in the base class, which does
@@ -41,6 +45,12 @@
 
 	private LinkedList outputStack = new LinkedList();
 
+	private List collectedParameters = new ArrayList();
+
+	public List getCollectedParameters() {
+		return collectedParameters;
+	}
+
 	protected void out(String s) {
 		writer.clause( s );
 	}
@@ -52,6 +62,18 @@
 		else {
 			super.out( n );
 		}
+
+		if ( n instanceof ParameterNode ) {
+			collectedParameters.add( ( ( ParameterNode ) n ).getHqlParameterSpecification() );
+		}
+		else if ( n instanceof ParameterContainer ) {
+			if ( ( ( ParameterContainer ) n ).hasEmbeddedParameters() ) {
+				ParameterSpecification[] specifications = ( ( ParameterContainer ) n ).getEmbeddedParameters();
+				if ( specifications != null ) {
+					collectedParameters.addAll( Arrays.asList( specifications ) );
+				}
+			}
+		}
 	}
 
 	protected void commaBetweenParameters(String comma) {

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -4,6 +4,8 @@
 import java.sql.PreparedStatement;
 import java.sql.Connection;
 import java.sql.Statement;
+import java.util.Collections;
+import java.util.List;
 
 import org.hibernate.HibernateException;
 import org.hibernate.action.BulkOperationCleanupAction;
@@ -34,6 +36,7 @@
 
 	private final Log log;
 	private final HqlSqlWalker walker;
+	private List idSelectParameterSpecifications = Collections.EMPTY_LIST;
 
 	public AbstractStatementExecutor(HqlSqlWalker walker, Log log) {
 		this.walker = walker;
@@ -48,6 +51,10 @@
 		return walker.getSessionFactoryHelper().getFactory();
 	}
 
+	protected List getIdSelectParameterSpecifications() {
+		return idSelectParameterSpecifications;
+	}
+
 	protected abstract Queryable[] getAffectedQueryables();
 
 	protected String generateIdInsertSelect(Queryable persister, String tableAlias, AST whereClause) {
@@ -80,6 +87,7 @@
 				SqlGenerator sqlGenerator = new SqlGenerator( getFactory() );
 				sqlGenerator.whereClause( whereClause );
 				userWhereClause = sqlGenerator.getSQL().substring( 7 );  // strip the " where "
+				idSelectParameterSpecifications = sqlGenerator.getCollectedParameters();
 			}
 			catch ( RecognitionException e ) {
 				throw new HibernateException( "Unable to generate id select for DML operation", e );

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/BasicExecutor.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/BasicExecutor.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/BasicExecutor.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -4,6 +4,7 @@
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.util.Iterator;
+import java.util.List;
 
 import org.hibernate.HibernateException;
 import org.hibernate.engine.QueryParameters;
@@ -31,6 +32,7 @@
 
 	private final Queryable persister;
 	private final String sql;
+	private final List parameterSpecifications;
 
 	public BasicExecutor(HqlSqlWalker walker, Queryable persister) {
 		super( walker, log );
@@ -40,6 +42,7 @@
 			gen.statement( walker.getAST() );
 			sql = gen.getSQL();
 			gen.getParseErrorHandler().throwQueryException();
+			parameterSpecifications = gen.getCollectedParameters();
 		}
 		catch ( RecognitionException e ) {
 			throw QuerySyntaxException.convert( e );
@@ -60,10 +63,10 @@
 		try {
 			try {
 				st = session.getBatcher().prepareStatement( sql );
-				Iterator paramSpecifications = getWalker().getParameters().iterator();
+				Iterator parameterSpecifications = this.parameterSpecifications.iterator();
 				int pos = 1;
-				while ( paramSpecifications.hasNext() ) {
-					final ParameterSpecification paramSpec = ( ParameterSpecification ) paramSpecifications.next();
+				while ( parameterSpecifications.hasNext() ) {
+					final ParameterSpecification paramSpec = ( ParameterSpecification ) parameterSpecifications.next();
 					pos += paramSpec.bind( st, parameters, session, pos );
 				}
 				if ( selection != null ) {

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -84,7 +84,7 @@
 			try {
 				try {
 					ps = session.getBatcher().prepareStatement( idInsertSelect );
-					Iterator paramSpecifications = getWalker().getParameters().iterator();
+					Iterator paramSpecifications = getIdSelectParameterSpecifications().iterator();
 					int pos = 1;
 					while ( paramSpecifications.hasNext() ) {
 						final ParameterSpecification paramSpec = ( ParameterSpecification ) paramSpecifications.next();

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -109,7 +109,7 @@
 				try {
 					ps = session.getBatcher().prepareStatement( idInsertSelect );
 					int parameterStart = getWalker().getNumberOfParametersInSetClause();
-					List allParams = getWalker().getParameters();
+					List allParams = getIdSelectParameterSpecifications();
 					Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
 					int sum = 1; // jdbc params are 1-based
 					while ( whereParams.hasNext() ) {

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromElement.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromElement.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromElement.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -3,8 +3,10 @@
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.ArrayList;
 
 import org.hibernate.QueryException;
+import org.hibernate.param.ParameterSpecification;
 import org.hibernate.engine.JoinSequence;
 import org.hibernate.hql.QueryTranslator;
 import org.hibernate.hql.CollectionProperties;
@@ -36,7 +38,7 @@
  * Date: Dec 6, 2003<br>
  * Time: 10:28:17 AM<br>
  */
-public class FromElement extends HqlSqlWalkerNode implements DisplayableNode {
+public class FromElement extends HqlSqlWalkerNode implements DisplayableNode, ParameterContainer {
 	private static final Log log = LogFactory.getLog( FromElement.class );
 
 	private String className;
@@ -548,4 +550,23 @@
 	public boolean isDereferencedBySubclassProperty() {
 		return dereferencedBySubclassProperty;
 	}
+
+
+	// ParameterContainer impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	private List embeddedParameters;
+
+	public void addEmbeddedParameter(ParameterSpecification specification) {
+		if ( embeddedParameters == null ) {
+			embeddedParameters = new ArrayList();
+		}
+		embeddedParameters.add( specification );
+	}
+
+	public boolean hasEmbeddedParameters() {
+		return embeddedParameters != null && ! embeddedParameters.isEmpty();
+	}
+
+	public ParameterSpecification[] getEmbeddedParameters() {
+		return ( ParameterSpecification[] ) embeddedParameters.toArray( new ParameterSpecification[ embeddedParameters.size() ] );
+	}
 }

Added: core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/ParameterContainer.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/ParameterContainer.java	                        (rev 0)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/ParameterContainer.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,77 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.hql.ast.tree;
+
+import org.hibernate.param.ParameterSpecification;
+
+/**
+ * Currently this is needed in order to deal with {@link FromElement FromElements} which
+ * conatin "hidden" JDBC parameters from applying filters.
+ * <p/>
+ * Would love for this to go away, but that would require that Hibernate's
+ * internal {@link org.hibernate.engine.JoinSequence join handling} be able to either:<ul>
+ * <li>render the same AST structures</li>
+ * <li>render structures capable of being converted to these AST structures</li>
+ * </ul>
+ * <p/>
+ * In the interim, this allows us to at least treat these "hidden" parameters properly which is
+ * the most pressing need.
+ *
+ * @deprecated
+ * @author Steve Ebersole
+ */
+public interface ParameterContainer {
+	/**
+	 * Set the renderable text of this node.
+	 *
+	 * @param text The renderable text
+	 */
+	public void setText(String text);
+
+	/**
+	 * Adds a parameter specification for a parameter encountered within this node.  We use the term 'embedded' here
+	 * because of the fact that the parameter was simply encountered as part of the node's text; it does not exist
+	 * as part of a subtree as it might in a true AST.
+	 *
+	 * @param specification The generated specification.
+	 */
+	public void addEmbeddedParameter(ParameterSpecification specification);
+
+	/**
+	 * Determine whether this node contans embedded parameters.  The implication is that
+	 * {@link #getEmbeddedParameters()} is allowed to return null if this method returns false.
+	 *
+	 * @return True if this node contains embedded parameters; false otherwise.
+	 */
+	public boolean hasEmbeddedParameters();
+
+	/**
+	 * Retrieve all embedded parameter specifications.
+	 *
+	 * @return All embedded parameter specifications; may return null.
+	 * @see #hasEmbeddedParameters()
+	 */
+	public ParameterSpecification[] getEmbeddedParameters();
+}

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/SqlFragment.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/SqlFragment.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/SqlFragment.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -1,14 +1,41 @@
-// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
 package org.hibernate.hql.ast.tree;
 
+import java.util.List;
+import java.util.ArrayList;
+
 import org.hibernate.sql.JoinFragment;
+import org.hibernate.param.ParameterSpecification;
 
 /**
  * Represents an SQL fragment in the AST.
  *
- * @author josh Dec 5, 2004 9:01:52 AM
+ * @author josh
  */
-public class SqlFragment extends Node {
+public class SqlFragment extends Node implements ParameterContainer {
 	private JoinFragment joinFragment;
 	private FromElement fromElement;
 
@@ -27,4 +54,23 @@
 	public FromElement getFromElement() {
 		return fromElement;
 	}
+
+
+	// ParameterContainer impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	private List embeddedParameters;
+
+	public void addEmbeddedParameter(ParameterSpecification specification) {
+		if ( embeddedParameters == null ) {
+			embeddedParameters = new ArrayList();
+		}
+		embeddedParameters.add( specification );
+	}
+
+	public boolean hasEmbeddedParameters() {
+		return embeddedParameters != null && ! embeddedParameters.isEmpty();
+	}
+
+	public ParameterSpecification[] getEmbeddedParameters() {
+		return ( ParameterSpecification[] ) embeddedParameters.toArray( new ParameterSpecification[ embeddedParameters.size() ] );
+	}
 }

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/JoinProcessor.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/JoinProcessor.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/JoinProcessor.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -4,22 +4,29 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.ListIterator;
-import java.util.Collections;
 import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Collection;
 
 import org.hibernate.AssertionFailure;
+import org.hibernate.param.DynamicFilterParameterSpecification;
+import org.hibernate.type.Type;
+import org.hibernate.impl.FilterImpl;
+import org.hibernate.dialect.Dialect;
 import org.hibernate.engine.JoinSequence;
+import org.hibernate.engine.QueryParameters;
 import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.QueryTranslatorImpl;
+import org.hibernate.hql.ast.HqlSqlWalker;
 import org.hibernate.hql.ast.tree.FromClause;
 import org.hibernate.hql.ast.tree.FromElement;
 import org.hibernate.hql.ast.tree.QueryNode;
 import org.hibernate.hql.ast.tree.DotNode;
+import org.hibernate.hql.ast.tree.ParameterContainer;
+import org.hibernate.hql.classic.ParserHelper;
 import org.hibernate.sql.JoinFragment;
 import org.hibernate.util.StringHelper;
+import org.hibernate.util.ArrayHelper;
 
-import antlr.ASTFactory;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -34,18 +41,17 @@
 
 	private static final Log log = LogFactory.getLog( JoinProcessor.class );
 
-	private QueryTranslatorImpl queryTranslatorImpl;
-	private SyntheticAndFactory andFactory;
+	private final HqlSqlWalker walker;
+	private final SyntheticAndFactory syntheticAndFactory;
 
 	/**
 	 * Constructs a new JoinProcessor.
 	 *
-	 * @param astFactory		  The factory for AST node creation.
-	 * @param queryTranslatorImpl The query translator.
+	 * @param walker The walker to which we are bound, giving us access to needed resources.
 	 */
-	public JoinProcessor(ASTFactory astFactory, QueryTranslatorImpl queryTranslatorImpl) {
-		this.andFactory = new SyntheticAndFactory( astFactory );
-		this.queryTranslatorImpl = queryTranslatorImpl;
+	public JoinProcessor(HqlSqlWalker walker) {
+		this.walker = walker;
+		this.syntheticAndFactory = new SyntheticAndFactory( walker );
 	}
 
 	/**
@@ -69,7 +75,7 @@
 		}
 	}
 
-	public void processJoins(QueryNode query, boolean inSubquery) {
+	public void processJoins(QueryNode query) {
 		final FromClause fromClause = query.getFromClause();
 
 		final List fromElements;
@@ -108,22 +114,21 @@
 								log.trace( "forcing inclusion of extra joins [alias=" + alias + ", containsTableAlias=" + containsTableAlias + "]" );
 								return true;
 							}
-							boolean shallowQuery = queryTranslatorImpl.isShallowQuery();
+							boolean shallowQuery = walker.isShallowQuery();
 							boolean includeSubclasses = fromElement.isIncludeSubclasses();
 							boolean subQuery = fromClause.isSubQuery();
 							return includeSubclasses && containsTableAlias && !subQuery && !shallowQuery;
 						}
 					}
 			);
-			addJoinNodes( query, join, fromElement, inSubquery );
+			addJoinNodes( query, join, fromElement );
 		}
 
 	}
 
-	private void addJoinNodes(QueryNode query, JoinSequence join, FromElement fromElement, boolean inSubquery) {
-		// Generate FROM and WHERE fragments for the from element.
+	private void addJoinNodes(QueryNode query, JoinSequence join, FromElement fromElement) {
 		JoinFragment joinFragment = join.toJoinFragment(
-				inSubquery ? Collections.EMPTY_MAP : queryTranslatorImpl.getEnabledFilters(),
+				walker.getEnabledFilters(),
 				fromElement.useFromFragment() || fromElement.isDereferencedBySuperclassOrSubclassProperty(),
 				fromElement.getWithClauseFragment(),
 				fromElement.getWithClauseJoinAlias()
@@ -143,13 +148,24 @@
 
 		// If there is a FROM fragment and the FROM element is an explicit, then add the from part.
 		if ( fromElement.useFromFragment() /*&& StringHelper.isNotEmpty( frag )*/ ) {
-			String fromFragment = processFromFragment( frag, join );
+			String fromFragment = processFromFragment( frag, join ).trim();
 			if ( log.isDebugEnabled() ) {
 				log.debug( "Using FROM fragment [" + fromFragment + "]" );
 			}
-			fromElement.setText( fromFragment.trim() ); // Set the text of the fromElement.
+			processDynamicFilterParameters(
+					fromFragment,
+					fromElement,
+					walker
+			);
 		}
-		andFactory.addWhereFragment( joinFragment, whereFrag, query, fromElement );
+
+		syntheticAndFactory.addWhereFragment(
+				joinFragment,
+				whereFrag,
+				query,
+				fromElement,
+				walker
+		);
 	}
 
 	private String processFromFragment(String frag, JoinSequence join) {
@@ -161,4 +177,56 @@
 		return fromFragment;
 	}
 
+	public static void processDynamicFilterParameters(
+			final String sqlFragment,
+			final ParameterContainer container,
+			final HqlSqlWalker walker) {
+		if ( walker.getEnabledFilters().isEmpty()
+				&& ( ! hasDynamicFilterParam( sqlFragment ) )
+				&& ( ! ( hasCollectionFilterParam( sqlFragment ) ) ) ) {
+			return;
+		}
+
+		Dialect dialect = walker.getSessionFactoryHelper().getFactory().getDialect();
+		String symbols = new StringBuffer().append( ParserHelper.HQL_SEPARATORS )
+				.append( dialect.openQuote() )
+				.append( dialect.closeQuote() )
+				.toString();
+		StringTokenizer tokens = new StringTokenizer( sqlFragment, symbols, true );
+		StringBuffer result = new StringBuffer();
+
+		while ( tokens.hasMoreTokens() ) {
+			final String token = tokens.nextToken();
+			if ( token.startsWith( ParserHelper.HQL_VARIABLE_PREFIX ) ) {
+				final String filterParameterName = token.substring( 1 );
+				final String[] parts = QueryParameters.parseFilterParameterName( filterParameterName );
+				final FilterImpl filter = ( FilterImpl ) walker.getEnabledFilters().get( parts[0] );
+				final Object value = filter.getParameter( parts[1] );
+				final Type type = filter.getFilterDefinition().getParameterType( parts[1] );
+				final String typeBindFragment = StringHelper.join(
+						",",
+						ArrayHelper.fillArray( "?", type.getColumnSpan( walker.getSessionFactoryHelper().getFactory() ) )
+				);
+				final String bindFragment = ( value != null && Collection.class.isInstance( value ) )
+						? StringHelper.join( ",", ArrayHelper.fillArray( typeBindFragment, ( ( Collection ) value ).size() ) )
+						: typeBindFragment;
+				result.append( bindFragment );
+				container.addEmbeddedParameter( new DynamicFilterParameterSpecification( parts[0], parts[1], type ) );
+			}
+			else {
+				result.append( token );
+			}
+		}
+
+		container.setText( result.toString() );
+	}
+
+	private static boolean hasDynamicFilterParam(String sqlFragment) {
+		return sqlFragment.indexOf( ParserHelper.HQL_VARIABLE_PREFIX ) < 0;
+	}
+
+	private static boolean hasCollectionFilterParam(String sqlFragment) {
+		return sqlFragment.indexOf( "?" ) < 0;
+	}
+
 }

Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/SyntheticAndFactory.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/SyntheticAndFactory.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/SyntheticAndFactory.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -2,18 +2,20 @@
 package org.hibernate.hql.ast.util;
 
 import java.util.Map;
-import java.util.StringTokenizer;
 
 import org.hibernate.hql.antlr.HqlSqlTokenTypes;
 import org.hibernate.hql.ast.tree.FromElement;
 import org.hibernate.hql.ast.tree.QueryNode;
 import org.hibernate.hql.ast.tree.RestrictableStatement;
 import org.hibernate.hql.ast.tree.SqlFragment;
+import org.hibernate.hql.ast.tree.Node;
+import org.hibernate.hql.ast.HqlSqlWalker;
 import org.hibernate.persister.entity.Queryable;
 import org.hibernate.sql.JoinFragment;
 import org.hibernate.util.StringHelper;
+import org.hibernate.type.Type;
+import org.hibernate.param.CollectionFilterKeyParameterSpecification;
 
-import antlr.ASTFactory;
 import antlr.collections.AST;
 
 import org.apache.commons.logging.Log;
@@ -27,27 +29,36 @@
 public class SyntheticAndFactory implements HqlSqlTokenTypes {
 	private static final Log log = LogFactory.getLog( SyntheticAndFactory.class );
 
-	private ASTFactory astFactory;
+	private HqlSqlWalker hqlSqlWalker;
 	private AST thetaJoins;
 	private AST filters;
 
-	public SyntheticAndFactory(ASTFactory astFactory) {
-		this.astFactory = astFactory;
+	public SyntheticAndFactory(HqlSqlWalker hqlSqlWalker) {
+		this.hqlSqlWalker = hqlSqlWalker;
 	}
 
-	public void addWhereFragment(JoinFragment joinFragment, String whereFragment, QueryNode query, FromElement fromElement) {
+	private Node create(int tokenType, String text) {
+		return ( Node ) ASTUtil.create( hqlSqlWalker.getASTFactory(), tokenType, text );
+	}
 
+	public void addWhereFragment(
+			JoinFragment joinFragment,
+			String whereFragment,
+			QueryNode query,
+			FromElement fromElement,
+			HqlSqlWalker hqlSqlWalker) {
 		if ( whereFragment == null ) {
 			return;
 		}
 
+		if ( !fromElement.useWhereFragment() && !joinFragment.hasThetaJoins() ) {
+			return;
+		}
+
 		whereFragment = whereFragment.trim();
 		if ( StringHelper.isEmpty( whereFragment ) ) {
 			return;
 		}
-		else if ( !fromElement.useWhereFragment() && !joinFragment.hasThetaJoins() ) {
-			return;
-		}
 
 		// Forcefully remove leading ands from where fragments; the grammar will
 		// handle adding them
@@ -55,12 +66,36 @@
 			whereFragment = whereFragment.substring( 4 );
 		}
 
-		if ( log.isDebugEnabled() ) log.debug( "Using WHERE fragment [" + whereFragment + "]" );
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Using unprocessed WHERE-fragment [" + whereFragment + "]");
+		}
 
-		SqlFragment fragment = ( SqlFragment ) ASTUtil.create( astFactory, SQL_TOKEN, whereFragment );
+		SqlFragment fragment = ( SqlFragment ) create( SQL_TOKEN, whereFragment );
 		fragment.setJoinFragment( joinFragment );
 		fragment.setFromElement( fromElement );
 
+		if ( hqlSqlWalker.isFilter() ) {
+			if ( whereFragment.indexOf( '?' ) >= 0 ) {
+				Type collectionFilterKeyType = hqlSqlWalker.getSessionFactoryHelper()
+						.requireQueryableCollection( hqlSqlWalker.getCollectionFilterRole() )
+						.getKeyType();
+				CollectionFilterKeyParameterSpecification paramSpec = new CollectionFilterKeyParameterSpecification(
+						hqlSqlWalker.getCollectionFilterRole(),
+						collectionFilterKeyType,
+						0
+				);
+				fragment.addEmbeddedParameter( paramSpec );
+			}
+		}
+
+		JoinProcessor.processDynamicFilterParameters(
+				whereFragment,
+				fragment,
+				hqlSqlWalker
+		);
+
+		log.debug( "Using processed WHERE-fragment [" + fragment.getText() + "]" );
+
 		// Filter conditions need to be inserted before the HQL where condition and the
 		// theta join node.  This is because org.hibernate.loader.Loader binds the filter parameters first,
 		// then it binds all the HQL query parameters, see org.hibernate.loader.Loader.processFilterParameters().
@@ -69,11 +104,11 @@
 				// Find or create the WHERE clause
 				AST where = query.getWhereClause();
 				// Create a new FILTERS node as a parent of all filters
-				filters = astFactory.create( FILTERS, "{filter conditions}" );
+				filters = create( FILTERS, "{filter conditions}" );
 				// Put the FILTERS node before the HQL condition and theta joins
 				ASTUtil.insertChild( where, filters );
 			}
-			
+
 			// add the current fragment to the FILTERS node
 			filters.addChild( fragment );
 		}
@@ -82,7 +117,7 @@
 				// Find or create the WHERE clause
 				AST where = query.getWhereClause();
 				// Create a new THETA_JOINS node as a parent of all filters
-				thetaJoins = astFactory.create( THETA_JOINS, "{theta joins}" );
+				thetaJoins = create( THETA_JOINS, "{theta joins}" );
 				// Put the THETA_JOINS node before the HQL condition, after the filters.
 				if (filters==null) {
 					ASTUtil.insertChild( where, thetaJoins );
@@ -91,14 +126,18 @@
 					ASTUtil.insertSibling( thetaJoins, filters );
 				}
 			}
-			
+
 			// add the current fragment to the THETA_JOINS node
 			thetaJoins.addChild(fragment);
 		}
 
 	}
 
-	public void addDiscriminatorWhereFragment(RestrictableStatement statement, Queryable persister, Map enabledFilters, String alias) {
+	public void addDiscriminatorWhereFragment(
+			RestrictableStatement statement,
+			Queryable persister,
+			Map enabledFilters,
+			String alias) {
 		String whereFragment = persister.filterFragment( alias, enabledFilters ).trim();
 		if ( "".equals( whereFragment ) ) {
 			return;
@@ -118,13 +157,19 @@
 		// At some point we probably want to apply an additional grammar to
 		// properly tokenize this where fragment into constituent parts
 		// focused on the operators embedded within the fragment.
-		AST discrimNode = astFactory.create( SQL_TOKEN, whereFragment );
+		SqlFragment discrimNode = ( SqlFragment ) create( SQL_TOKEN, whereFragment );
 
+		JoinProcessor.processDynamicFilterParameters(
+				whereFragment,
+				discrimNode,
+				hqlSqlWalker
+		);
+
 		if ( statement.getWhereClause().getNumberOfChildren() == 0 ) {
 			statement.getWhereClause().setFirstChild( discrimNode );
 		}
 		else {
-			AST and = astFactory.create( AND, "{and}" );
+			AST and = create( AND, "{and}" );
 			AST currentFirstChild = statement.getWhereClause().getFirstChild();
 			and.setFirstChild( discrimNode );
 			and.addChild( currentFirstChild );

Modified: core/branches/Branch_3_2/src/org/hibernate/loader/hql/QueryLoader.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/loader/hql/QueryLoader.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/loader/hql/QueryLoader.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -483,8 +483,8 @@
 			final QueryParameters queryParameters,
 			final int startIndex,
 			final SessionImplementor session) throws SQLException {
-		int position = bindFilterParameterValues( statement, queryParameters, startIndex, session );
-		List parameterSpecs = queryTranslator.getSqlAST().getWalker().getParameters();
+		int position = startIndex;
+		List parameterSpecs = queryTranslator.getCollectedParameterSpecifications();
 		Iterator itr = parameterSpecs.iterator();
 		while ( itr.hasNext() ) {
 			ParameterSpecification spec = ( ParameterSpecification ) itr.next();

Modified: core/branches/Branch_3_2/src/org/hibernate/param/CollectionFilterKeyParameterSpecification.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/param/CollectionFilterKeyParameterSpecification.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/param/CollectionFilterKeyParameterSpecification.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -8,13 +8,12 @@
 import org.hibernate.type.Type;
 
 /**
- * A specialized ParameterSpecification impl for dealing with a collection-key
- * as part of a collection filter compilation.
+ * A specialized ParameterSpecification impl for dealing with a collection-key as part of a collection filter
+ * compilation.
  *
  * @author Steve Ebersole
  */
 public class CollectionFilterKeyParameterSpecification implements ParameterSpecification {
-
 	private final String collectionRole;
 	private final Type keyType;
 	private final int queryParameterPosition;
@@ -34,6 +33,9 @@
 		this.queryParameterPosition = queryParameterPosition;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public int bind(
 			PreparedStatement statement,
 			QueryParameters qp,
@@ -44,14 +46,23 @@
 		return keyType.getColumnSpan( session.getFactory() );
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public Type getExpectedType() {
 		return keyType;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public void setExpectedType(Type expectedType) {
 		// todo : throw exception?
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public String renderDisplayInfo() {
 		return "collection-filter-key=" + collectionRole;
 	}

Modified: core/branches/Branch_3_2/src/org/hibernate/param/DynamicFilterParameterSpecification.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/param/DynamicFilterParameterSpecification.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/param/DynamicFilterParameterSpecification.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -2,20 +2,17 @@
 
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Iterator;
 
 import org.hibernate.engine.QueryParameters;
 import org.hibernate.engine.SessionImplementor;
 import org.hibernate.type.Type;
 
 /**
- * A specialized ParameterSpecification impl for dealing with a dynamic filter
- * parameters.
- * <p/>
- * Note: this class is currently not used.  The ideal way to deal with dynamic filter
- * parameters for HQL would be to track them just as we do with other parameters
- * in the translator.  However, the problem with that is that we currently do not
- * know the filters which actually apply to the query; we know the active/enabled ones,
- * but not the ones that actually "make it into" the resulting query.
+ * A specialized ParameterSpecification impl for dealing with a dynamic filter parameters.
+ * 
+ * @see org.hibernate.Session#enableFilter(String)
  *
  * @author Steve Ebersole
  */
@@ -23,37 +20,65 @@
 	private final String filterName;
 	private final String parameterName;
 	private final Type definedParameterType;
-	private final int queryParameterPosition;
 
+	/**
+	 * Constructs a parameter specification for a particular filter parameter.
+	 *
+	 * @param filterName The name of the filter
+	 * @param parameterName The name of the parameter
+	 * @param definedParameterType The paremeter type specified on the filter metadata
+	 */
 	public DynamicFilterParameterSpecification(
 			String filterName,
 			String parameterName,
-			Type definedParameterType,
-			int queryParameterPosition) {
+			Type definedParameterType) {
 		this.filterName = filterName;
 		this.parameterName = parameterName;
 		this.definedParameterType = definedParameterType;
-		this.queryParameterPosition = queryParameterPosition;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public int bind(
 			PreparedStatement statement,
 			QueryParameters qp,
 			SessionImplementor session,
-			int position) throws SQLException {
-		Object value = qp.getFilteredPositionalParameterValues()[queryParameterPosition];
-		definedParameterType.nullSafeSet( statement, value, position, session );
-		return definedParameterType.getColumnSpan( session.getFactory() );
+			int start) throws SQLException {
+		final int columnSpan = definedParameterType.getColumnSpan( session.getFactory() );
+		final Object value = session.getFilterParameterValue( filterName + '.' + parameterName );
+		if ( Collection.class.isInstance( value ) ) {
+			int positions = 0;
+			Iterator itr = ( ( Collection ) value ).iterator();
+			while ( itr.hasNext() ) {
+				definedParameterType.nullSafeSet( statement, itr.next(), start + positions, session );
+				positions += columnSpan;
+			}
+			return positions;
+		}
+		else {
+			definedParameterType.nullSafeSet( statement, value, start, session );
+			return columnSpan;
+		}
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public Type getExpectedType() {
 		return definedParameterType;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public void setExpectedType(Type expectedType) {
-		// todo : throw exception?
+		// todo : throw exception?  maybe warn if not the same?
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public String renderDisplayInfo() {
 		return "dynamic-filter={filterName=" + filterName + ",paramName=" + parameterName + "}";
 	}

Modified: core/branches/Branch_3_2/src/org/hibernate/param/NamedParameterSpecification.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/param/NamedParameterSpecification.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/param/NamedParameterSpecification.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -9,14 +9,20 @@
 import java.sql.SQLException;
 
 /**
- * Relates to an explicit query named-parameter.
+ * Parameter bind specification for an explicit named parameter.
  *
  * @author Steve Ebersole
  */
 public class NamedParameterSpecification extends AbstractExplicitParameterSpecification implements ParameterSpecification {
-
 	private final String name;
 
+	/**
+	 * Constructs a named parameter bind specification.
+	 *
+	 * @param sourceLine See {@link #getSourceLine()}
+	 * @param sourceColumn See {@link #getSourceColumn()} 
+	 * @param name The named parameter name.
+	 */
 	public NamedParameterSpecification(int sourceLine, int sourceColumn, String name) {
 		super( sourceLine, sourceColumn );
 		this.name = name;
@@ -39,10 +45,18 @@
 		return typedValue.getType().getColumnSpan( session.getFactory() );
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public String renderDisplayInfo() {
 		return "name=" + name + ", expectedType=" + getExpectedType();
 	}
 
+	/**
+	 * Getter for property 'name'.
+	 *
+	 * @return Value for property 'name'.
+	 */
 	public String getName() {
 		return name;
 	}

Modified: core/branches/Branch_3_2/src/org/hibernate/param/PositionalParameterSpecification.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/param/PositionalParameterSpecification.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/param/PositionalParameterSpecification.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -9,14 +9,20 @@
 import java.sql.SQLException;
 
 /**
- * Relates to an explicit query positional (or ordinal) parameter.
+ * Parameter bind specification for an explicit  positional (or ordinal) parameter.
  *
  * @author Steve Ebersole
  */
 public class PositionalParameterSpecification extends AbstractExplicitParameterSpecification implements ParameterSpecification {
-
 	private final int hqlPosition;
 
+	/**
+	 * Constructs a position/ordinal parameter bind specification.
+	 *
+	 * @param sourceLine See {@link #getSourceLine()}
+	 * @param sourceColumn See {@link #getSourceColumn()}
+	 * @param hqlPosition The position in the source query, relative to the other source positional parameters.
+	 */
 	public PositionalParameterSpecification(int sourceLine, int sourceColumn, int hqlPosition) {
 		super( sourceLine, sourceColumn );
 		this.hqlPosition = hqlPosition;
@@ -40,10 +46,18 @@
 		return type.getColumnSpan( session.getFactory() );
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public String renderDisplayInfo() {
 		return "ordinal=" + hqlPosition + ", expectedType=" + getExpectedType();
 	}
 
+	/**
+	 * Getter for property 'hqlPosition'.
+	 *
+	 * @return Value for property 'hqlPosition'.
+	 */
 	public int getHqlPosition() {
 		return hqlPosition;
 	}

Modified: core/branches/Branch_3_2/src/org/hibernate/param/VersionTypeSeedParameterSpecification.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/param/VersionTypeSeedParameterSpecification.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/src/org/hibernate/param/VersionTypeSeedParameterSpecification.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -11,20 +11,24 @@
 import java.sql.SQLException;
 
 /**
- * Implementation of VersionTypeSeedParameterSpecification.
+ * Parameter bind specification used for optimisitc lock version seeding (from insert statements).
  *
  * @author Steve Ebersole
  */
 public class VersionTypeSeedParameterSpecification implements ParameterSpecification {
-
 	private VersionType type;
 
+	/**
+	 * Constructs a version seed parameter bind specification.
+	 *
+	 * @param type The version type.
+	 */
 	public VersionTypeSeedParameterSpecification(VersionType type) {
 		this.type = type;
 	}
 
 	/**
-	 * @see org.hibernate.param.ParameterSpecification#bind
+	 * {@inheritDoc}
 	 */
 	public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position)
 	        throws SQLException {
@@ -32,14 +36,23 @@
 		return 1;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public Type getExpectedType() {
 		return type;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public void setExpectedType(Type expectedType) {
 		// expected type is intrinsic here...
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public String renderDisplayInfo() {
 		return "version-seed, type=" + type;
 	}

Modified: core/branches/Branch_3_2/test/org/hibernate/test/filter/DynamicFilterTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/DynamicFilterTest.java	2008-10-01 19:03:53 UTC (rev 15239)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/DynamicFilterTest.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -10,26 +10,26 @@
 import java.util.Set;
 
 import junit.framework.Test;
-import junit.framework.TestSuite;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.hibernate.EntityMode;
 import org.hibernate.FetchMode;
 import org.hibernate.Hibernate;
 import org.hibernate.Session;
 import org.hibernate.Transaction;
-import org.hibernate.junit.functional.FunctionalTestCase;
-import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.Criteria;
+import org.hibernate.impl.SessionFactoryImpl;
+import org.hibernate.engine.SessionImplementor;
 import org.hibernate.cache.CacheKey;
 import org.hibernate.cache.entry.CollectionCacheEntry;
 import org.hibernate.cfg.Configuration;
 import org.hibernate.cfg.Environment;
-import org.hibernate.criterion.Expression;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.impl.SessionFactoryImpl;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.criterion.DetachedCriteria;
+import org.hibernate.criterion.Property;
+import org.hibernate.criterion.Subqueries;
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
 import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.test.TestCase;
 import org.hibernate.transform.DistinctRootEntityResultTransformer;
 
 /**
@@ -39,8 +39,6 @@
  */
 public class DynamicFilterTest extends FunctionalTestCase {
 
-	private Log log = LogFactory.getLog( DynamicFilterTest.class );
-
 	public DynamicFilterTest(String testName) {
 		super( testName );
 	}
@@ -79,6 +77,7 @@
 		testData.prepare();
 
 		Session session = openSession();
+		long ts = ( ( SessionImplementor ) session ).getTimestamp();
 
 		// Force a collection into the second level cache, with its non-filtered elements
 		Salesperson sp = ( Salesperson ) session.load( Salesperson.class, testData.steveId );
@@ -93,6 +92,7 @@
 		session.close();
 
 		session = openSession();
+		ts = ( ( SessionImplementor ) session ).getTimestamp();
 		session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() );
 		sp = ( Salesperson ) session.createQuery( "from Salesperson as s where s.id = :id" )
 		        .setLong( "id", testData.steveId.longValue() )
@@ -152,7 +152,6 @@
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 		// HQL test
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-		log.info( "Starting HQL filter tests" );
 		TestData testData = new TestData();
 		testData.prepare();
 
@@ -162,13 +161,11 @@
 		session.enableFilter( "effectiveDate" )
 		        .setParameter( "asOfDate", testData.lastMonth.getTime() );
 
-		log.info( "HQL against Salesperson..." );
 		List results = session.createQuery( "select s from Salesperson as s left join fetch s.orders" ).list();
 		assertTrue( "Incorrect filtered HQL result count [" + results.size() + "]", results.size() == 1 );
 		Salesperson result = ( Salesperson ) results.get( 0 );
 		assertTrue( "Incorrect collectionfilter count", result.getOrders().size() == 1 );
 
-		log.info( "HQL against Product..." );
 		results = session.createQuery( "from Product as p where p.stockNumber = ?" ).setInteger( 0, 124 ).list();
 		assertTrue( results.size() == 1 );
 
@@ -180,7 +177,6 @@
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 		// Criteria-query test
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-		log.info( "Starting Criteria-query filter tests" );
 		TestData testData = new TestData();
 		testData.prepare();
 
@@ -193,16 +189,14 @@
 		session.enableFilter( "effectiveDate" )
 		        .setParameter( "asOfDate", testData.lastMonth.getTime() );
 
-		log.info( "Criteria query against Salesperson..." );
 		List salespersons = session.createCriteria( Salesperson.class )
 		        .setFetchMode( "orders", FetchMode.JOIN )
 		        .list();
 		assertEquals( "Incorrect salesperson count", 1, salespersons.size() );
 		assertEquals( "Incorrect order count", 1, ( ( Salesperson ) salespersons.get( 0 ) ).getOrders().size() );
 
-		log.info( "Criteria query against Product..." );
 		List products = session.createCriteria( Product.class )
-		        .add( Expression.eq( "stockNumber", new Integer( 124 ) ) )
+		        .add( Restrictions.eq( "stockNumber", new Integer( 124 ) ) )
 		        .list();
 		assertEquals( "Incorrect product count", 1, products.size() );
 
@@ -210,18 +204,292 @@
 		testData.release();
 	}
 
+	public void testCriteriaControl() {
+		TestData testData = new TestData();
+		testData.prepare();
+
+		// the subquery...
+		DetachedCriteria subquery = DetachedCriteria.forClass( Salesperson.class )
+				.setProjection( Property.forName( "name" ) );
+
+		Session session = openSession();
+		session.beginTransaction();
+		session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() );
+		session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "APAC" } );
+
+		List result = session.createCriteria( Order.class )
+				.add( Subqueries.in( "steve", subquery ) )
+				.list();
+		assertEquals( 1, result.size() );
+
+		session.getTransaction().commit();
+		session.close();
+
+		testData.release();
+	}
+
+	public void testCriteriaSubqueryWithFilters() {
+		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		// Criteria-subquery test
+		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		TestData testData = new TestData();
+		testData.prepare();
+
+		Session session = openSession();
+		session.enableFilter("region").setParameter("region", "APAC");
+
+		DetachedCriteria salespersonSubquery = DetachedCriteria.forClass(Salesperson.class)
+				.add(Restrictions.eq("name", "steve"))
+				.setProjection(Property.forName("department"));
+
+		Criteria departmentsQuery = session.createCriteria(Department.class).add(Subqueries.propertyIn("id", salespersonSubquery));
+		List departments = departmentsQuery.list();
+
+		assertEquals("Incorrect department count", 1, departments.size());
+
+		session.enableFilter("region").setParameter("region", "Foobar");
+		departments = departmentsQuery.list();
+
+		assertEquals("Incorrect department count", 0, departments.size());
+
+		session.enableFilter("region").setParameter("region", "APAC");
+
+		DetachedCriteria lineItemSubquery = DetachedCriteria.forClass(LineItem.class)
+				.add(Restrictions.ge("quantity", 1L))
+				.createCriteria("product")
+				.add(Restrictions.eq("name", "Acme Hair Gel"))
+				.setProjection(Property.forName("id"));
+
+		List orders = session.createCriteria(Order.class)
+				.add(Subqueries.exists(lineItemSubquery))
+				.add(Restrictions.eq("buyer", "gavin"))
+				.list();
+
+		assertEquals("Incorrect orders count", 1, orders.size());
+
+		session.enableFilter("region").setParameter("region", "APAC");
+		session.enableFilter("effectiveDate").setParameter("asOfDate", testData.lastMonth.getTime());
+
+		DetachedCriteria productSubquery = DetachedCriteria.forClass(Product.class)
+				.add(Restrictions.eq("name", "Acme Hair Gel"))
+				.setProjection(Property.forName("id"));
+
+		lineItemSubquery = DetachedCriteria.forClass(LineItem.class)
+				.add(Restrictions.ge("quantity", 1L))
+				.createCriteria("product")
+				.add(Subqueries.propertyIn("id", productSubquery))
+				.setProjection(Property.forName("id"));
+
+		orders = session.createCriteria(Order.class)
+				.add(Subqueries.exists(lineItemSubquery))
+				.add(Restrictions.eq("buyer", "gavin"))
+				.list();
+
+		assertEquals("Incorrect orders count", 1, orders.size());
+
+		session.enableFilter("region").setParameter("region", "APAC");
+		session.enableFilter("effectiveDate").setParameter("asOfDate", testData.fourMonthsAgo.getTime());
+
+		orders = session.createCriteria(Order.class)
+				.add(Subqueries.exists(lineItemSubquery))
+				.add(Restrictions.eq("buyer", "gavin"))
+				.list();
+
+		assertEquals("Incorrect orders count", 0, orders.size());
+
+		session.close();
+		testData.release();
+	}
+
+	public void testHQLSubqueryWithFilters() {
+		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		// HQL subquery with filters test
+		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		TestData testData = new TestData();
+		testData.prepare();
+
+		Session session = openSession();
+		session.enableFilter("region").setParameter("region", "APAC");
+
+		List departments = session.createQuery("select d from Department as d where d.id in (select s.department from Salesperson s where s.name = ?)").setString(0, "steve").list();
+
+		assertEquals("Incorrect department count", 1, departments.size());
+
+		session.enableFilter("region").setParameter("region", "Foobar");
+		departments = session.createQuery("select d from Department as d where d.id in (select s.department from Salesperson s where s.name = ?)").setString(0, "steve").list();
+
+		assertEquals("Incorrect department count", 0, departments.size());
+
+		session.enableFilter("region").setParameter("region", "APAC");
+
+		List orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li, Product as p where p.id = li.product and li.quantity >= ? and p.name = ?) and o.buyer = ?")
+				.setLong(0, 1L).setString(1, "Acme Hair Gel").setString(2, "gavin").list();
+
+		assertEquals("Incorrect orders count", 1, orders.size());
+
+		session.enableFilter("region").setParameter("region", "APAC");
+		session.enableFilter("effectiveDate").setParameter("asOfDate", testData.lastMonth.getTime());
+
+		orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ? and li.product in (select p.id from Product p where p.name = ?)) and o.buyer = ?")
+				.setLong(0, 1L).setString(1, "Acme Hair Gel").setString(2, "gavin").list();
+
+		assertEquals("Incorrect orders count", 1, orders.size());
+
+		session.enableFilter("region").setParameter("region", "APAC");
+		session.enableFilter("effectiveDate").setParameter("asOfDate", testData.fourMonthsAgo.getTime());
+
+		orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ? and li.product in (select p.id from Product p where p.name = ?)) and o.buyer = ?")
+				.setLong(0, 1L).setString(1, "Acme Hair Gel").setString(2, "gavin").list();
+
+		assertEquals("Incorrect orders count", 0, orders.size());
+
+		session.enableFilter("region").setParameter("region", "APAC");
+		session.enableFilter("effectiveDate").setParameter("asOfDate", testData.lastMonth.getTime());
+
+		orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li where li.quantity >= :quantity and li.product in (select p.id from Product p where p.name = :name)) and o.buyer = :buyer")
+				.setLong("quantity", 1L).setString("name", "Acme Hair Gel").setString("buyer", "gavin").list();
+
+		assertEquals("Incorrect orders count", 1, orders.size());
+
+		session.enableFilter("region").setParameter("region", "APAC");
+		session.enableFilter("effectiveDate").setParameter("asOfDate", testData.lastMonth.getTime());
+
+		orders = session.createQuery("select o from Order as o where exists (select li.id from LineItem li where li.quantity >= ? and li.product in (select p.id from Product p where p.name = ?)) and o.buyer = :buyer")
+				.setLong(0, 1L).setString(1, "Acme Hair Gel").setString("buyer", "gavin").list();
+
+		assertEquals("Incorrect orders count", 1, orders.size());
+
+		session.close();
+		testData.release();
+	}
+
+	public void testFilterApplicationOnHqlQueryWithImplicitSubqueryContainingPositionalParameter() {
+		TestData testData = new TestData();
+		testData.prepare();
+
+		Session session = openSession();
+		session.beginTransaction();
+
+		final String queryString = "from Order o where ? in ( select sp.name from Salesperson sp )";
+
+		// first a control-group query
+		List result = session.createQuery( queryString ).setParameter( 0, "steve" ).list();
+		assertEquals( 2, result.size() );
+
+		// now lets enable filters on Order...
+		session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() );
+		result = session.createQuery( queryString ).setParameter( 0, "steve" ).list();
+		assertEquals( 1, result.size() );
+
+		// now, lets additionally enable filter on Salesperson.  First a valid one...
+		session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "APAC" } );
+		result = session.createQuery( queryString ).setParameter( 0, "steve" ).list();
+		assertEquals( 1, result.size() );
+
+		// ... then a silly one...
+		session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "gamma quadrant" } );
+		result = session.createQuery( queryString ).setParameter( 0, "steve" ).list();
+		assertEquals( 0, result.size() );
+
+		session.getTransaction().commit();
+		session.close();
+
+		testData.release();
+	}
+
+	public void testFilterApplicationOnHqlQueryWithImplicitSubqueryContainingNamedParameter() {
+		TestData testData = new TestData();
+		testData.prepare();
+
+		Session session = openSession();
+		session.beginTransaction();
+
+		final String queryString = "from Order o where :salesPersonName in ( select sp.name from Salesperson sp )";
+
+		// first a control-group query
+		List result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list();
+		assertEquals( 2, result.size() );
+
+		// now lets enable filters on Order...
+		session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() );
+		result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list();
+		assertEquals( 1, result.size() );
+
+		// now, lets additionally enable filter on Salesperson.  First a valid one...
+		session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "APAC" } );
+		result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list();
+		assertEquals( 1, result.size() );
+
+		// ... then a silly one...
+		session.enableFilter( "regionlist" ).setParameterList( "regions", new String[] { "gamma quadrant" } );
+		result = session.createQuery( queryString ).setParameter( "salesPersonName", "steve" ).list();
+		assertEquals( 0, result.size() );
+
+		session.getTransaction().commit();
+		session.close();
+
+		testData.release();
+	}
+
+	public void testFiltersOnSimpleHqlDelete() {
+		Session session = openSession();
+		session.beginTransaction();
+		Salesperson sp = new Salesperson();
+		sp.setName( "steve" );
+		sp.setRegion( "NA" );
+		session.persist( sp );
+		Salesperson sp2 = new Salesperson();
+		sp2.setName( "john" );
+		sp2.setRegion( "APAC" );
+		session.persist( sp2 );
+		session.getTransaction().commit();
+		session.close();
+
+		session = openSession();
+		session.beginTransaction();
+		session.enableFilter( "region" ).setParameter( "region", "NA" );
+		int count = session.createQuery( "delete from Salesperson" ).executeUpdate();
+		assertEquals( 1, count );
+		session.delete( sp2 );
+		session.getTransaction().commit();
+		session.close();
+	}
+
+	public void testFiltersOnMultiTableHqlDelete() {
+		Session session = openSession();
+		session.beginTransaction();
+		Salesperson sp = new Salesperson();
+		sp.setName( "steve" );
+		sp.setRegion( "NA" );
+		session.persist( sp );
+		Salesperson sp2 = new Salesperson();
+		sp2.setName( "john" );
+		sp2.setRegion( "APAC" );
+		session.persist( sp2 );
+		session.getTransaction().commit();
+		session.close();
+
+		session = openSession();
+		session.beginTransaction();
+		session.enableFilter( "region" ).setParameter( "region", "NA" );
+		int count = session.createQuery( "delete from Salesperson" ).executeUpdate();
+		assertEquals( 1, count );
+		session.delete( sp2 );
+		session.getTransaction().commit();
+		session.close();
+	}
+
+
 	public void testGetFilters() {
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 		// Get() test
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-		log.info( "Starting get() filter tests (eager assoc. fetching)." );
 		TestData testData = new TestData();
 		testData.prepare();
 
 		Session session = openSession();
 		session.enableFilter( "region" ).setParameter( "region", "APAC" );
 
-		log.info( "Performing get()..." );
 		Salesperson salesperson = ( Salesperson ) session.get( Salesperson.class, testData.steveId );
 		assertNotNull( salesperson );
 		assertEquals( "Incorrect order count", 1, salesperson.getOrders().size() );
@@ -234,7 +502,6 @@
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 		// one-to-many loading tests
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-		log.info( "Starting one-to-many collection loader filter tests." );
 		TestData testData = new TestData();
 		testData.prepare();
 
@@ -242,7 +509,6 @@
 		session.enableFilter( "seniorSalespersons" )
 		        .setParameter( "asOfDate", testData.lastMonth.getTime() );
 
-		log.info( "Performing load of Department..." );
 		Department department = ( Department ) session.load( Department.class, testData.deptId );
 		Set salespersons = department.getSalespersons();
 		assertEquals( "Incorrect salesperson count", 1, salespersons.size() );
@@ -255,7 +521,6 @@
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 		// one-to-many loading tests
 		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-		log.info( "Starting one-to-many collection loader filter tests." );
 		TestData testData = new TestData();
 		testData.prepare();
 
@@ -263,7 +528,6 @@
 		session.enableFilter( "regionlist" )
 		        .setParameterList( "regions", new String[]{"LA", "APAC"} );
 
-		log.debug( "Performing query of Salespersons" );
 		List salespersons = session.createQuery( "from Salesperson" ).list();
 		assertEquals( "Incorrect salesperson count", 1, salespersons.size() );
 
@@ -280,7 +544,7 @@
 
 		Product prod = ( Product ) session.createCriteria( Product.class )
 		        .setResultTransformer( new DistinctRootEntityResultTransformer() )
-		        .add( Expression.eq( "id", testData.prod1Id ) )
+		        .add( Restrictions.eq( "id", testData.prod1Id ) )
 		        .uniqueResult();
 
 		assertNotNull( prod );
@@ -420,7 +684,7 @@
 		Session session = openSession();
 
 		List result = session.createCriteria( Product.class )
-		        .add( Expression.eq( "id", testData.prod1Id ) )
+		        .add( Restrictions.eq( "id", testData.prod1Id ) )
 		        .list();
 
 		Product prod = ( Product ) result.get( 0 );

Added: core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Basic.hbm.xml
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Basic.hbm.xml	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Basic.hbm.xml	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Middleware LLC.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  ~
+  -->
+
+<!DOCTYPE hibernate-mapping
+        SYSTEM
+        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+
+<hibernate-mapping package="org.hibernate.test.filter.hql">
+    <class name="Person" table="FILTER_HQL_PERSON">
+        <id column="ID" name="id" type="long">
+            <generator class="increment"/>
+        </id>
+        <property name="name" type="string"/>
+        <property name="sex" column="SEX_CODE" type="char"/>
+        <filter name="sex"/>
+    </class>
+</hibernate-mapping>

Added: core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/BasicFilteredBulkManipulationTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/BasicFilteredBulkManipulationTest.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/BasicFilteredBulkManipulationTest.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,93 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.test.filter.hql;
+
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.Session;
+
+/**
+ * Tests for application of filters 
+ *
+ * @author Steve Ebersole
+ */
+public class BasicFilteredBulkManipulationTest extends FunctionalTestCase {
+	public BasicFilteredBulkManipulationTest(String string) {
+		super( string );
+	}
+
+	public String[] getMappings() {
+		return new String[]{
+			"filter/hql/filter-defs.hbm.xml",
+			"filter/hql/Basic.hbm.xml"
+		};
+	}
+
+	public void testBasicFilteredHqlDelete() {
+		Session s = openSession();
+		s.beginTransaction();
+		s.save( new Person( "Steve", 'M' ) );
+		s.save( new Person( "Emmanuel", 'M' ) );
+		s.save( new Person( "Gail", 'F' ) );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.enableFilter( "sex" ).setParameter( "sexCode", new Character( 'M' ) );
+		int count = s.createQuery( "delete Person" ).executeUpdate();
+		assertEquals( 2, count );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.createQuery( "delete Person" ).executeUpdate();
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testBasicFilteredHqlUpdate() {
+		Session s = openSession();
+		s.beginTransaction();
+		s.save( new Person( "Shawn", 'M' ) );
+		s.save( new Person( "Sally", 'F' ) );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.enableFilter( "sex" ).setParameter( "sexCode", new Character( 'M' ) );
+		int count = s.createQuery( "update Person p set p.name = 'Shawn'" ).executeUpdate();
+		assertEquals( 1, count );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.createQuery( "delete Person" ).executeUpdate();
+		s.getTransaction().commit();
+		s.close();
+	}
+}

Added: core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Customer.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Customer.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Customer.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,51 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.test.filter.hql;
+
+/**
+ * Leaf subclass
+ *
+ * @author Steve Ebersole
+ */
+public class Customer extends User {
+	private String company;
+
+	protected Customer() {
+		super();
+	}
+
+	public Customer(String name, char sex, String username, String company) {
+		super( name, sex, username );
+		this.company = company;
+	}
+
+	public String getCompany() {
+		return company;
+	}
+
+	public void setCompany(String company) {
+		this.company = company;
+	}
+}

Added: core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Employee.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Employee.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Employee.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,53 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.test.filter.hql;
+
+import java.util.Date;
+
+/**
+ * Leaf subclass
+ *
+ * @author Steve Ebersole
+ */
+public class Employee extends User {
+	private Date hireDate;
+
+	protected Employee() {
+		super();
+	}
+
+	public Employee(String name, char sex, String username, Date hireDate) {
+		super( name, sex, username );
+		this.hireDate = hireDate;
+	}
+
+	public Date getHireDate() {
+		return hireDate;
+	}
+
+	public void setHireDate(Date hireDate) {
+		this.hireDate = hireDate;
+	}
+}

Added: core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Joined.hbm.xml
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Joined.hbm.xml	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Joined.hbm.xml	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Middleware LLC.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  ~
+  -->
+
+<!DOCTYPE hibernate-mapping
+        SYSTEM
+        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+
+<hibernate-mapping package="org.hibernate.test.filter.hql">
+    <class name="Person" table="FILTER_HQL_JOINED_PERSON">
+        <id column="ID" name="id" type="long">
+            <generator class="increment"/>
+        </id>
+        <property name="name" type="string"/>
+        <property name="sex" column="SEX_CODE" type="char"/>
+        <joined-subclass name="User" table="FILTER_HQL_JOINED_USER">
+            <key column="USER_ID"/>
+            <property name="username" type="string"/>
+            <joined-subclass name="Employee" table="FILTER_HQL_JOINED_EMP">
+                <key column="EMP_ID"/>
+                <property name="hireDate" type="date"/>
+            </joined-subclass>
+            <joined-subclass name="Customer" table="FILTER_HQL_JOINED_CUST">
+                <key column="CUST_ID"/>
+                <property name="company" type="string"/>
+            </joined-subclass>
+        </joined-subclass>
+        <filter name="sex"/>
+    </class>
+</hibernate-mapping>

Added: core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/JoinedFilteredBulkManipulationTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/JoinedFilteredBulkManipulationTest.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/JoinedFilteredBulkManipulationTest.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,201 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.test.filter.hql;
+
+import java.util.Date;
+
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.Session;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class JoinedFilteredBulkManipulationTest extends FunctionalTestCase {
+	public JoinedFilteredBulkManipulationTest(String string) {
+		super( string );
+	}
+
+	public String[] getMappings() {
+		return new String[]{
+			"filter/hql/filter-defs.hbm.xml",
+			"filter/hql/Joined.hbm.xml"
+		};
+	}
+
+	public void testFilteredJoinedSubclassHqlDeleteRoot() {
+		Session s = openSession();
+		s.beginTransaction();
+		s.save( new Employee( "John", 'M', "john", new Date() ) );
+		s.save( new Employee( "Jane", 'F', "jane", new Date() ) );
+		s.save( new Customer( "Charlie", 'M', "charlie", "Acme" ) );
+		s.save( new Customer( "Wanda", 'F', "wanda", "ABC" ) );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.enableFilter( "sex" ).setParameter( "sexCode", new Character('M' ) );
+		int count = s.createQuery( "delete Person" ).executeUpdate();
+		assertEquals( 2, count );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.createQuery( "delete Person" ).executeUpdate();
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testFilteredJoinedSubclassHqlDeleteNonLeaf() {
+		Session s = openSession();
+		s.beginTransaction();
+		s.save( new Employee( "John", 'M', "john", new Date() ) );
+		s.save( new Employee( "Jane", 'F', "jane", new Date() ) );
+		s.save( new Customer( "Charlie", 'M', "charlie", "Acme" ) );
+		s.save( new Customer( "Wanda", 'F', "wanda", "ABC" ) );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.enableFilter( "sex" ).setParameter( "sexCode", new Character('M' ) );
+		int count = s.createQuery( "delete User" ).executeUpdate();
+		assertEquals( 2, count );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.createQuery( "delete Person" ).executeUpdate();
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testFilteredJoinedSubclassHqlDeleteLeaf() {
+		Session s = openSession();
+		s.beginTransaction();
+		s.save( new Employee( "John", 'M', "john", new Date() ) );
+		s.save( new Employee( "Jane", 'F', "jane", new Date() ) );
+		s.save( new Customer( "Charlie", 'M', "charlie", "Acme" ) );
+		s.save( new Customer( "Wanda", 'F', "wanda", "ABC" ) );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.enableFilter( "sex" ).setParameter( "sexCode", new Character('M' ) );
+		int count = s.createQuery( "delete Employee" ).executeUpdate();
+		assertEquals( 1, count );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.createQuery( "delete Person" ).executeUpdate();
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testFilteredJoinedSubclassHqlUpdateRoot() {
+		Session s = openSession();
+		s.beginTransaction();
+		s.save( new Employee( "John", 'M', "john", new Date() ) );
+		s.save( new Employee( "Jane", 'F', "jane", new Date() ) );
+		s.save( new Customer( "Charlie", 'M', "charlie", "Acme" ) );
+		s.save( new Customer( "Wanda", 'F', "wanda", "ABC" ) );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.enableFilter( "sex" ).setParameter( "sexCode", new Character('M' ) );
+		int count = s.createQuery( "update Person p set p.name = '<male>'" ).executeUpdate();
+		assertEquals( 2, count );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.createQuery( "delete Person" ).executeUpdate();
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testFilteredJoinedSubclassHqlUpdateNonLeaf() {
+		Session s = openSession();
+		s.beginTransaction();
+		s.save( new Employee( "John", 'M', "john", new Date() ) );
+		s.save( new Employee( "Jane", 'F', "jane", new Date() ) );
+		s.save( new Customer( "Charlie", 'M', "charlie", "Acme" ) );
+		s.save( new Customer( "Wanda", 'F', "wanda", "ABC" ) );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.enableFilter( "sex" ).setParameter( "sexCode", new Character('M' ) );
+		int count = s.createQuery( "update User u set u.username = :un where u.name = :n" )
+				.setString( "un", "charlie" )
+				.setString( "n", "Wanda" )
+				.executeUpdate();
+		assertEquals( 0, count );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.createQuery( "delete Person" ).executeUpdate();
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testFilteredJoinedSubclassHqlUpdateLeaf() {
+		Session s = openSession();
+		s.beginTransaction();
+		s.save( new Employee( "John", 'M', "john", new Date() ) );
+		s.save( new Employee( "Jane", 'F', "jane", new Date() ) );
+		s.save( new Customer( "Charlie", 'M', "charlie", "Acme" ) );
+		s.save( new Customer( "Wanda", 'F', "wanda", "ABC" ) );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.enableFilter( "sex" ).setParameter( "sexCode", new Character('M' ) );
+		int count = s.createQuery( "update Customer c set c.company = 'XYZ'" ).executeUpdate();
+		assertEquals( 1, count );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		s.createQuery( "delete Person" ).executeUpdate();
+		s.getTransaction().commit();
+		s.close();
+	}
+}

Added: core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Person.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Person.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/Person.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,71 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.test.filter.hql;
+
+/**
+ * Base of inheritence hierarchy
+ *
+ * @author Steve Ebersole
+ */
+public class Person {
+	private Long id;
+	private String name;
+	private char sex;
+
+	/**
+	 * Used by persistence
+	 */
+	protected Person() {
+	}
+
+	public Person(String name, char sex) {
+		this.name = name;
+		this.sex = sex;
+	}
+
+	public Long getId() {
+		return id;
+	}
+
+	private void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public char getSex() {
+		return sex;
+	}
+
+	public void setSex(char sex) {
+		this.sex = sex;
+	}
+}

Added: core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/User.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/User.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/User.java	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,51 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.test.filter.hql;
+
+/**
+ * Non-leaf subclass
+ *
+ * @author Steve Ebersole
+ */
+public class User extends Person {
+	private String username;
+
+	protected User() {
+		super();
+	}
+
+	public User(String name, char sex, String username) {
+		super( name, sex );
+		this.username = username;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+}

Added: core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/filter-defs.hbm.xml
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/filter-defs.hbm.xml	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/filter/hql/filter-defs.hbm.xml	2008-10-01 19:32:11 UTC (rev 15240)
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Middleware LLC.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  ~
+  -->
+
+<!DOCTYPE hibernate-mapping
+        SYSTEM
+        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+
+<hibernate-mapping package="org.hibernate.test.filter.hql">
+    <filter-def name="sex" condition="SEX_CODE = :sexCode">
+        <filter-param name="sexCode" type="char"/>
+    </filter-def>
+</hibernate-mapping>




More information about the hibernate-commits mailing list