[hibernate-commits] Hibernate SVN: r11686 - in trunk/Hibernate3/code: core/src/main/java/org/hibernate/loader and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Jun 13 14:31:11 EDT 2007


Author: cbredesen
Date: 2007-06-13 14:31:11 -0400 (Wed, 13 Jun 2007)
New Revision: 11686

Modified:
   trunk/Hibernate3/code/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java
   trunk/Hibernate3/code/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java
   trunk/Hibernate3/code/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java
   trunk/Hibernate3/code/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
Log:
HHH-952: subqueries with joins using DetatchedCriteria

Modified: trunk/Hibernate3/code/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java
===================================================================
--- trunk/Hibernate3/code/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java	2007-06-13 18:19:43 UTC (rev 11685)
+++ trunk/Hibernate3/code/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java	2007-06-13 18:31:11 UTC (rev 11686)
@@ -1,17 +1,17 @@
 //$Id: SubqueryExpression.java 7365 2005-07-04 02:40:29Z oneovthafew $
 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,6 +24,7 @@
 	private String op;
 	private QueryParameters params;
 	private Type[] types;
+	private CriteriaQueryTranslator innerQuery;
 	
 	protected Type[] getTypes() {
 		return types;
@@ -40,33 +41,22 @@
 	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 +67,48 @@
 
 	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: trunk/Hibernate3/code/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java
===================================================================
--- trunk/Hibernate3/code/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java	2007-06-13 18:19:43 UTC (rev 11685)
+++ trunk/Hibernate3/code/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java	2007-06-13 18:31:11 UTC (rev 11686)
@@ -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,17 +43,15 @@
 		final String orderByString,
 		final LockMode lockMode)
 	throws MappingException {
-		
 		walkEntityTree( persister, getAlias() );
-		
 		List allAssociations = new ArrayList();
 		allAssociations.addAll(associations);
-		allAssociations.add( new OuterJoinableAssociation( 
+		allAssociations.add( new OuterJoinableAssociation(
 				persister.getEntityType(),
-				null, 
-				null, 
-				alias, 
-				JoinFragment.LEFT_OUTER_JOIN, 
+				null,
+				null,
+				alias,
+				JoinFragment.LEFT_OUTER_JOIN,
 				getFactory(),
 				CollectionHelper.EMPTY_MAP
 			) );
@@ -57,7 +59,6 @@
 		initPersisters(allAssociations, lockMode);
 		initStatementString( whereString, orderByString, lockMode);
 	}
-	
 	protected final void initProjection(
 		final String projectionString,
 		final String whereString,

Modified: trunk/Hibernate3/code/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java
===================================================================
--- trunk/Hibernate3/code/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java	2007-06-13 18:19:43 UTC (rev 11685)
+++ trunk/Hibernate3/code/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java	2007-06-13 18:31:11 UTC (rev 11686)
@@ -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,9 +55,19 @@
 			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;
 

Modified: trunk/Hibernate3/code/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
===================================================================
--- trunk/Hibernate3/code/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java	2007-06-13 18:19:43 UTC (rev 11685)
+++ trunk/Hibernate3/code/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java	2007-06-13 18:31:11 UTC (rev 11686)
@@ -169,8 +169,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 +177,7 @@
 	
 		session.createCriteria(Enrolment.class, "e")
 			.add( Subqueries.eq("Gavin King", dc3) )
-			.list();*/
+			.list();
 
 		session.delete(enrolment2);
 		session.delete(gavin);




More information about the hibernate-commits mailing list