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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue May 20 02:44:01 EDT 2008


Author: anthonyHib
Date: 2008-05-20 02:44:01 -0400 (Tue, 20 May 2008)
New Revision: 14676

Modified:
   core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/criterion/SubqueryExpression.java
   core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/loader/AbstractEntityJoinWalker.java
   core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java
   core/branches/Branch_3_2_4_SP1_CP/test/org/hibernate/test/criteria/CriteriaQueryTest.java
Log:
fix for JBPAPP-838/HHH-957/HHH-952

Modified: core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/criterion/SubqueryExpression.java
===================================================================
--- core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/criterion/SubqueryExpression.java	2008-05-19 15:22:26 UTC (rev 14675)
+++ core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/criterion/SubqueryExpression.java	2008-05-20 06:44:01 UTC (rev 14676)
@@ -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_4_SP1_CP/src/org/hibernate/loader/AbstractEntityJoinWalker.java
===================================================================
--- core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/loader/AbstractEntityJoinWalker.java	2008-05-19 15:22:26 UTC (rev 14675)
+++ core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/loader/AbstractEntityJoinWalker.java	2008-05-20 06:44:01 UTC (rev 14676)
@@ -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_4_SP1_CP/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java
===================================================================
--- core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java	2008-05-19 15:22:26 UTC (rev 14675)
+++ core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java	2008-05-20 06:44:01 UTC (rev 14676)
@@ -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_4_SP1_CP/test/org/hibernate/test/criteria/CriteriaQueryTest.java
===================================================================
--- core/branches/Branch_3_2_4_SP1_CP/test/org/hibernate/test/criteria/CriteriaQueryTest.java	2008-05-19 15:22:26 UTC (rev 14675)
+++ core/branches/Branch_3_2_4_SP1_CP/test/org/hibernate/test/criteria/CriteriaQueryTest.java	2008-05-20 06:44:01 UTC (rev 14676)
@@ -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);
@@ -225,110 +223,130 @@
 		session.close();
 	}
 	
-		public void testProjectionCache() {
-			Session s = openSession();
-			Transaction t = s.beginTransaction();
-			
-			Course course = new Course();
-			course.setCourseCode("HIB");
-			course.setDescription("Hibernate Training");
-			s.save(course);
-			
-			Student gavin = new Student();
-			gavin.setName("Gavin King");
-			gavin.setStudentNumber(666);
-			s.save(gavin);
-			
-			Student xam = new Student();
-			xam.setName("Max Rydahl Andersen");
-			xam.setStudentNumber(101);
-			s.save(xam);
-			
-			Enrolment enrolment1 = new Enrolment();
-			enrolment1.setCourse(course);
-			enrolment1.setCourseCode(course.getCourseCode());
-			enrolment1.setSemester((short) 1);
-			enrolment1.setYear((short) 1999);
-			enrolment1.setStudent(xam);
-			enrolment1.setStudentNumber(xam.getStudentNumber());
-			xam.getEnrolments().add(enrolment1);
-			s.save(enrolment1);
-			
-			Enrolment enrolment2 = new Enrolment();
-			enrolment2.setCourse(course);
-			enrolment2.setCourseCode(course.getCourseCode());
-			enrolment2.setSemester((short) 3);
-			enrolment2.setYear((short) 1998);
-			enrolment2.setStudent(gavin);
-			enrolment2.setStudentNumber(gavin.getStudentNumber());
-			gavin.getEnrolments().add(enrolment2);
-			s.save(enrolment2);
-			
-			List list = s.createCriteria(Enrolment.class)
-				.createAlias("student", "s")
-				.createAlias("course", "c")
-				.add( Restrictions.isNotEmpty("s.enrolments") )
-				.setProjection( Projections.projectionList()
-						.add( Projections.property("s.name") )
-						.add( Projections.property("c.description") )
-				)
-				.setCacheable(true)
-				.list();
-			
-			assertEquals( list.size(), 2 );
-			assertEquals( ( (Object[]) list.get(0) ).length, 2 );
-			assertEquals( ( (Object[]) list.get(1) ).length, 2 );
-			
-			t.commit();
-			s.close();
+	// test for HHH-957/JBPAPP-838
+	public void testDetachedCriteriaAsSubQuery() {
+		
+		DetachedCriteria subselect = DetachedCriteria.forClass(Course.class);
+		subselect.add(Restrictions.like("description","test",MatchMode.START)).setProjection(Projections.property("courseCode"));
+
+		DetachedCriteria mainselect = DetachedCriteria.forClass(Enrolment.class);
+		mainselect.createCriteria("student").add(Subqueries.in("preferredCourse",subselect));
+
+		
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+		
+		mainselect.getExecutableCriteria(session).list();
+		
+		t.commit();
+		session.close();
+	}
+
+
+	public void testProjectionCache() {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		
+		Course course = new Course();
+		course.setCourseCode("HIB");
+		course.setDescription("Hibernate Training");
+		s.save(course);
+		
+		Student gavin = new Student();
+		gavin.setName("Gavin King");
+		gavin.setStudentNumber(666);
+		s.save(gavin);
+		
+		Student xam = new Student();
+		xam.setName("Max Rydahl Andersen");
+		xam.setStudentNumber(101);
+		s.save(xam);
+		
+		Enrolment enrolment1 = new Enrolment();
+		enrolment1.setCourse(course);
+		enrolment1.setCourseCode(course.getCourseCode());
+		enrolment1.setSemester((short) 1);
+		enrolment1.setYear((short) 1999);
+		enrolment1.setStudent(xam);
+		enrolment1.setStudentNumber(xam.getStudentNumber());
+		xam.getEnrolments().add(enrolment1);
+		s.save(enrolment1);
+		
+		Enrolment enrolment2 = new Enrolment();
+		enrolment2.setCourse(course);
+		enrolment2.setCourseCode(course.getCourseCode());
+		enrolment2.setSemester((short) 3);
+		enrolment2.setYear((short) 1998);
+		enrolment2.setStudent(gavin);
+		enrolment2.setStudentNumber(gavin.getStudentNumber());
+		gavin.getEnrolments().add(enrolment2);
+		s.save(enrolment2);
+		
+		List list = s.createCriteria(Enrolment.class)
+			.createAlias("student", "s")
+			.createAlias("course", "c")
+			.add( Restrictions.isNotEmpty("s.enrolments") )
+			.setProjection( Projections.projectionList()
+					.add( Projections.property("s.name") )
+					.add( Projections.property("c.description") )
+			)
+			.setCacheable(true)
+			.list();
+		
+		assertEquals( list.size(), 2 );
+		assertEquals( ( (Object[]) list.get(0) ).length, 2 );
+		assertEquals( ( (Object[]) list.get(1) ).length, 2 );
+		
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		
+		s.createCriteria(Enrolment.class)
+			.createAlias("student", "s")
+			.createAlias("course", "c")
+			.add( Restrictions.isNotEmpty("s.enrolments") )
+			.setProjection( Projections.projectionList()
+					.add( Projections.property("s.name") )
+					.add( Projections.property("c.description") )
+			)
+			.setCacheable(true)
+			.list();
 	
-			s = openSession();
-			t = s.beginTransaction();
-			
-			s.createCriteria(Enrolment.class)
-				.createAlias("student", "s")
-				.createAlias("course", "c")
-				.add( Restrictions.isNotEmpty("s.enrolments") )
-				.setProjection( Projections.projectionList()
-						.add( Projections.property("s.name") )
-						.add( Projections.property("c.description") )
-				)
-				.setCacheable(true)
-				.list();
+		assertEquals( list.size(), 2 );
+		assertEquals( ( (Object[]) list.get(0) ).length, 2 );
+		assertEquals( ( (Object[]) list.get(1) ).length, 2 );
 		
-			assertEquals( list.size(), 2 );
-			assertEquals( ( (Object[]) list.get(0) ).length, 2 );
-			assertEquals( ( (Object[]) list.get(1) ).length, 2 );
-			
-			t.commit();
-			s.close();
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		
+		s.createCriteria(Enrolment.class)
+			.createAlias("student", "s")
+			.createAlias("course", "c")
+			.add( Restrictions.isNotEmpty("s.enrolments") )
+			.setProjection( Projections.projectionList()
+					.add( Projections.property("s.name") )
+					.add( Projections.property("c.description") )
+			)
+			.setCacheable(true)
+			.list();
+		
+		assertEquals( list.size(), 2 );
+		assertEquals( ( (Object[]) list.get(0) ).length, 2 );
+		assertEquals( ( (Object[]) list.get(1) ).length, 2 );
+		
+		s.delete(enrolment1);
+		s.delete(enrolment2);
+		s.delete(course);
+		s.delete(gavin);
+		s.delete(xam);
 	
-			s = openSession();
-			t = s.beginTransaction();
-			
-			s.createCriteria(Enrolment.class)
-				.createAlias("student", "s")
-				.createAlias("course", "c")
-				.add( Restrictions.isNotEmpty("s.enrolments") )
-				.setProjection( Projections.projectionList()
-						.add( Projections.property("s.name") )
-						.add( Projections.property("c.description") )
-				)
-				.setCacheable(true)
-				.list();
-			
-			assertEquals( list.size(), 2 );
-			assertEquals( ( (Object[]) list.get(0) ).length, 2 );
-			assertEquals( ( (Object[]) list.get(1) ).length, 2 );
-			
-			s.delete(enrolment1);
-			s.delete(enrolment2);
-			s.delete(course);
-			s.delete(gavin);
-			s.delete(xam);
-		
-			t.commit();
-			s.close();
+		t.commit();
+		s.close();
 	}
 	
 	public void testProjections() {
@@ -398,8 +416,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();
@@ -797,4 +815,3 @@
 		session.close();
 	}
 }
-




More information about the hibernate-commits mailing list