[hibernate-commits] Hibernate SVN: r14209 - in core/branches/Branch_3_2: src/org/hibernate/loader and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Nov 28 20:36:04 EST 2007


Author: gbadner
Date: 2007-11-28 20:36:04 -0500 (Wed, 28 Nov 2007)
New Revision: 14209

Modified:
   core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java
   core/branches/Branch_3_2/src/org/hibernate/loader/AbstractEntityJoinWalker.java
   core/branches/Branch_3_2/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java
   core/branches/Branch_3_2/test/org/hibernate/test/criteria/CriteriaQueryTest.java
Log:
HHH-952 : subqueries with joins using DetatchedCriteria


Modified: core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java	2007-11-28 22:10:08 UTC (rev 14208)
+++ core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java	2007-11-29 01:36:04 UTC (rev 14209)
@@ -1,17 +1,18 @@
 //$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.SessionImplementor;
 import org.hibernate.engine.TypedValue;
 import org.hibernate.impl.CriteriaImpl;
+import org.hibernate.loader.criteria.CriteriaJoinWalker;
 import org.hibernate.loader.criteria.CriteriaQueryTranslator;
 import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.sql.Select;
 import org.hibernate.type.Type;
 
 /**
@@ -24,7 +25,8 @@
 	private String op;
 	private QueryParameters params;
 	private Type[] types;
-	
+	private CriteriaQueryTranslator innerQuery;
+
 	protected Type[] getTypes() {
 		return types;
 	}
@@ -39,34 +41,23 @@
 
 	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
 	throws HibernateException {
-		
-		final SessionImplementor session = ( (CriteriaImpl) criteria ).getSession(); //ugly!
-		final SessionFactoryImplementor factory = session.getFactory();
-		
+
+		final SessionFactoryImplementor factory = criteriaQuery.getFactory();
 		final OuterJoinLoadable persister = (OuterJoinLoadable) factory.getEntityPersister( criteriaImpl.getEntityOrClassName() );
-		CriteriaQueryTranslator innerQuery = new CriteriaQueryTranslator( 
-				factory, 
-				criteriaImpl, 
-				criteriaImpl.getEntityOrClassName(), //implicit polymorphism not supported (would need a union) 
-				criteriaQuery.generateSQLAlias(),
-				criteriaQuery
-			);
+
+		createAndSetInnerQuery( criteriaQuery, factory );
 		
-		params = innerQuery.getQueryParameters(); //TODO: bad lifecycle....
-		types = innerQuery.getProjectedTypes();
-		
-		//String filter = persister.filterFragment( innerQuery.getRootSQLALias(), session.getEnabledFilters() );
-		
-		String sql = new Select( factory.getDialect() )
-			.setWhereClause( innerQuery.getWhereCondition() )
-			.setGroupByClause( innerQuery.getGroupBy() )
-			.setSelectClause( innerQuery.getSelect() )
-			.setFromClause(
-					persister.fromTableFragment( innerQuery.getRootSQLALias() ) +   
-					persister.fromJoinFragment( innerQuery.getRootSQLALias(), true, false )
-				)
-			.toStatementString();
-		
+		CriteriaJoinWalker walker = new CriteriaJoinWalker(
+				persister,
+				innerQuery,
+				factory,
+				criteriaImpl,
+				criteriaImpl.getEntityOrClassName(),
+				new HashMap(),
+				innerQuery.getRootSQLALias());
+
+		String sql = walker.getSQLString();
+
 		final StringBuffer buf = new StringBuffer()
 			.append( toLeftSqlString(criteria, criteriaQuery) );
 		if (op!=null) buf.append(' ').append(op).append(' ');
@@ -77,13 +68,49 @@
 
 	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
 	throws HibernateException {
-		Type[] types = params.getPositionalParameterTypes();
-		Object[] values = params.getPositionalParameterValues();
-		TypedValue[] tv = new TypedValue[types.length];
-		for ( int i=0; i<types.length; i++ ) {
-			tv[i] = new TypedValue( types[i], values[i], EntityMode.POJO );
+		//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];
+		for ( int i=0; i<ppTypes.length; i++ ) {
+			tv[i] = new TypedValue( ppTypes[i], ppValues[i], EntityMode.POJO );
 		}
 		return tv;
 	}
 
+	/**
+	 * Creates the inner query used to extract some useful information about
+	 * types, since it is needed in both methods.
+	 * @param criteriaQuery
+	 * @param factory
+	 */
+	private void createAndSetInnerQuery(CriteriaQuery criteriaQuery, final SessionFactoryImplementor factory) {
+		if ( innerQuery == null ) {
+			//with two-deep subqueries, the same alias would get generated for
+			//both using the old method (criteriaQuery.generateSQLAlias()), so
+			//that is now used as a fallback if the main criteria alias isn't set
+			String alias;
+			if ( this.criteriaImpl.getAlias() == null ) {
+				alias = criteriaQuery.generateSQLAlias();
+			}
+			else {
+				alias = this.criteriaImpl.getAlias() + "_";
+			}
+
+			innerQuery = new CriteriaQueryTranslator(
+					factory,
+					criteriaImpl,
+					criteriaImpl.getEntityOrClassName(), //implicit polymorphism not supported (would need a union)
+					alias,
+					criteriaQuery
+				);
+
+			params = innerQuery.getQueryParameters();
+			types = innerQuery.getProjectedTypes();
+		}
+	}
 }

Modified: core/branches/Branch_3_2/src/org/hibernate/loader/AbstractEntityJoinWalker.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/loader/AbstractEntityJoinWalker.java	2007-11-28 22:10:08 UTC (rev 14208)
+++ core/branches/Branch_3_2/src/org/hibernate/loader/AbstractEntityJoinWalker.java	2007-11-29 01:36:04 UTC (rev 14209)
@@ -26,12 +26,16 @@
 public abstract class AbstractEntityJoinWalker extends JoinWalker {
 
 	private final OuterJoinLoadable persister;
-	private String alias;
+	private final String alias;
 
 	public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor factory, Map enabledFilters) {
+		this( persister, factory, enabledFilters, null );
+	}
+
+	public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor factory, Map enabledFilters, String alias) {
 		super( factory, enabledFilters );
 		this.persister = persister;
-		alias = generateRootAlias( persister.getEntityName() );
+		this.alias = ( alias == null ) ? generateRootAlias( persister.getEntityName() ) : alias;
 	}
 
 	protected final void initAll(
@@ -39,9 +43,7 @@
 		final String orderByString,
 		final LockMode lockMode)
 	throws MappingException {
-
 		walkEntityTree( persister, getAlias() );
-
 		List allAssociations = new ArrayList();
 		allAssociations.addAll(associations);
 		allAssociations.add( new OuterJoinableAssociation(

Modified: core/branches/Branch_3_2/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java	2007-11-28 22:10:08 UTC (rev 14208)
+++ core/branches/Branch_3_2/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java	2007-11-29 01:36:04 UTC (rev 14209)
@@ -8,7 +8,6 @@
 
 import org.hibernate.Criteria;
 import org.hibernate.FetchMode;
-import org.hibernate.HibernateException;
 import org.hibernate.LockMode;
 import org.hibernate.MappingException;
 import org.hibernate.engine.CascadeStyle;
@@ -18,7 +17,6 @@
 import org.hibernate.persister.entity.Joinable;
 import org.hibernate.persister.entity.OuterJoinLoadable;
 import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.JoinFragment;
 import org.hibernate.type.AssociationType;
 import org.hibernate.type.Type;
 import org.hibernate.type.TypeFactory;
@@ -57,10 +55,20 @@
 			final SessionFactoryImplementor factory, 
 			final CriteriaImpl criteria, 
 			final String rootEntityName,
-			final Map enabledFilters)
-	throws HibernateException {
-		super(persister, factory, enabledFilters);
+			final Map enabledFilters) {
+		this(persister, translator, factory, criteria, rootEntityName, enabledFilters, null);
+	}
 
+	public CriteriaJoinWalker(
+			final OuterJoinLoadable persister,
+			final CriteriaQueryTranslator translator,
+			final SessionFactoryImplementor factory,
+			final CriteriaImpl criteria,
+			final String rootEntityName,
+			final Map enabledFilters,
+			final String alias) {
+		super(persister, factory, enabledFilters, alias);
+
 		this.translator = translator;
 
 		querySpaces = translator.getQuerySpaces();

Modified: core/branches/Branch_3_2/test/org/hibernate/test/criteria/CriteriaQueryTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/criteria/CriteriaQueryTest.java	2007-11-28 22:10:08 UTC (rev 14208)
+++ core/branches/Branch_3_2/test/org/hibernate/test/criteria/CriteriaQueryTest.java	2007-11-29 01:36:04 UTC (rev 14209)
@@ -16,7 +16,6 @@
 import org.hibernate.cfg.Environment;
 import org.hibernate.criterion.DetachedCriteria;
 import org.hibernate.criterion.Example;
-import org.hibernate.criterion.Expression;
 import org.hibernate.criterion.MatchMode;
 import org.hibernate.criterion.Order;
 import org.hibernate.criterion.Projection;
@@ -154,8 +153,8 @@
 			.list();
 	
 		session.createCriteria(Student.class)
-		.add( Property.forName("name").eqAll(dc) )
-		.list();
+			.add( Property.forName("name").eqAll(dc) )
+			.list();
 	
 		session.createCriteria(Student.class)
 			.add( Subqueries.in("Gavin King", dc) )
@@ -169,8 +168,7 @@
 			.add( Subqueries.eq("Gavin King", dc2) )
 			.list();
 
-		//TODO: join in subselect: HHH-952
-		/*DetachedCriteria dc3 = DetachedCriteria.forClass(Student.class, "st")
+		DetachedCriteria dc3 = DetachedCriteria.forClass(Student.class, "st")
 			.createCriteria("enrolments")
 				.createCriteria("course")
 					.add( Property.forName("description").eq("Hibernate Training") )
@@ -178,7 +176,7 @@
 	
 		session.createCriteria(Enrolment.class, "e")
 			.add( Subqueries.eq("Gavin King", dc3) )
-			.list();*/
+			.list();
 
 		session.delete(enrolment2);
 		session.delete(gavin);
@@ -398,8 +396,8 @@
 					.add( Projections.property("studentNumber"), "stNumber" )
 					.add( Projections.property("courseCode"), "cCode" ) )
 			)
-		    .add( Expression.gt( "studentNumber", new Long(665) ) )
-		    .add( Expression.lt( "studentNumber", new Long(668) ) )
+		    .add( Restrictions.gt( "studentNumber", new Long(665) ) )
+		    .add( Restrictions.lt( "studentNumber", new Long(668) ) )
 		    .addOrder( Order.asc("stNumber") )
 			.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
 			.list();




More information about the hibernate-commits mailing list