[hibernate-commits] Hibernate SVN: r19183 - in core/trunk: core/src/main/java/org/hibernate/loader/criteria and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Apr 7 20:24:13 EDT 2010


Author: gbadner
Date: 2010-04-07 20:24:12 -0400 (Wed, 07 Apr 2010)
New Revision: 19183

Modified:
   core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java
   core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java
   core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java
   core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
Log:
HHH-5063 HHH-5082 : Invalid projections when alias is same as property name; QueryException thrown when grouping by component

Modified: core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java	2010-04-07 22:46:58 UTC (rev 19182)
+++ core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java	2010-04-08 00:24:12 UTC (rev 19183)
@@ -44,11 +44,19 @@
 	/**
 	 * Get the names of the columns mapped by a property path,
 	 * ignoring projection aliases
+	 * @throws org.hibernate.QueryException if the property maps to more than 1 column
 	 */
 	public String getColumn(Criteria criteria, String propertyPath) 
 	throws HibernateException;
 	
 	/**
+	 * Get the names of the columns mapped by a property path,
+	 * ignoring projection aliases
+	 */
+	public String[] getColumns(String propertyPath, Criteria criteria)
+	throws HibernateException;
+
+	/**
 	 * Get the type of a property path, ignoring projection aliases
 	 */
 	public Type getType(Criteria criteria, String propertyPath)

Modified: core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java	2010-04-07 22:46:58 UTC (rev 19182)
+++ core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java	2010-04-08 00:24:12 UTC (rev 19183)
@@ -27,6 +27,7 @@
 import org.hibernate.Criteria;
 import org.hibernate.HibernateException;
 import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
 
 /**
  * A property value, or grouped property value
@@ -62,7 +63,7 @@
 	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
 	throws HibernateException {
 		StringBuffer buf = new StringBuffer();
-		String[] cols = criteriaQuery.getColumnsUsingProjection( criteria, propertyName );
+		String[] cols = criteriaQuery.getColumns( propertyName, criteria );
 		for ( int i=0; i<cols.length; i++ ) {
 			buf.append( cols[i] )
 				.append(" as y")
@@ -84,7 +85,7 @@
 			return super.toGroupSqlString(criteria, criteriaQuery);
 		}
 		else {
-			return criteriaQuery.getColumn(criteria, propertyName);
+			return StringHelper.join( ", ", criteriaQuery.getColumns( propertyName, criteria ) );
 		}
 	}
 

Modified: core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java	2010-04-07 22:46:58 UTC (rev 19182)
+++ core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java	2010-04-08 00:24:12 UTC (rev 19183)
@@ -477,7 +477,7 @@
 		);
 	}
 
-	private String[] getColumns(
+	public String[] getColumns(
 			String propertyName,
 	        Criteria subcriteria) throws HibernateException {
 		return getPropertyMapping( getEntityName( subcriteria, propertyName ) )

Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java	2010-04-07 22:46:58 UTC (rev 19182)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java	2010-04-08 00:24:12 UTC (rev 19183)
@@ -1,6 +1,7 @@
 //$Id: CriteriaQueryTest.java 10976 2006-12-12 23:22:26Z steve.ebersole at jboss.com $
 package org.hibernate.test.criteria;
 
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -9,6 +10,8 @@
 import org.hibernate.Criteria;
 import org.hibernate.FetchMode;
 import org.hibernate.Hibernate;
+import org.hibernate.JDBCException;
+import org.hibernate.QueryException;
 import org.hibernate.ScrollableResults;
 import org.hibernate.Session;
 import org.hibernate.Transaction;
@@ -186,7 +189,143 @@
 		session.close();
 		
 	}
-	
+
+	public void testSubselectWithComponent() {
+
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+
+		Course course = new Course();
+		course.setCourseCode("HIB");
+		course.setDescription("Hibernate Training");
+		session.persist(course);
+
+		CityState odessaWa = new CityState( "Odessa", "WA" );
+
+		Student gavin = new Student();
+		gavin.setName("Gavin King");
+		gavin.setStudentNumber(232);
+		gavin.setCityState( odessaWa );
+		session.persist(gavin);
+
+		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);
+		session.persist(enrolment2);
+
+		DetachedCriteria dc = DetachedCriteria.forClass(Student.class)
+			.add( Property.forName("cityState").eq( odessaWa ) )
+			.setProjection( Property.forName("cityState") );
+
+		session.createCriteria(Student.class)
+			.add( Subqueries.exists(dc) )
+			.list();
+		t.commit();
+		session.close();
+
+		session = openSession();
+		t = session.beginTransaction();
+		try {
+			session.createCriteria(Student.class)
+				.add( Subqueries.propertyEqAll("cityState", dc) )
+				.list();
+			fail( "should have failed because cannot compare subquery results with multiple columns" );
+		}
+		catch ( QueryException ex ) {
+			// expected
+		}
+		finally {
+			t.rollback();
+			session.close();
+		}
+
+		session = openSession();
+		t = session.beginTransaction();
+		try {
+			session.createCriteria(Student.class)
+				.add( Property.forName("cityState").eqAll(dc) )
+				.list();
+			fail( "should have failed because cannot compare subquery results with multiple columns" );
+		}
+		catch ( QueryException ex ) {
+			// expected
+		}
+		finally {
+			t.rollback();
+			session.close();
+		}
+
+		session = openSession();
+		t = session.beginTransaction();
+		try {
+			session.createCriteria(Student.class)
+				.add( Subqueries.in( odessaWa, dc) )
+				.list();
+			fail( "should have failed because cannot compare subquery results with multiple columns" );
+		}
+		catch ( JDBCException ex ) {
+			// expected
+		}
+		finally {
+			t.rollback();
+			session.close();
+		}
+
+		session = openSession();
+		t = session.beginTransaction();
+		DetachedCriteria dc2 = DetachedCriteria.forClass(Student.class, "st1")
+			.add( Property.forName("st1.cityState").eqProperty("st2.cityState") )
+			.setProjection( Property.forName("cityState") );
+		try {
+			session.createCriteria(Student.class, "st2")
+				.add( Subqueries.eq( odessaWa, dc2) )
+				.list();
+			fail( "should have failed because cannot compare subquery results with multiple columns" );
+		}
+		catch ( JDBCException ex ) {
+			// expected
+		}
+		finally {
+			t.rollback();
+			session.close();
+		}
+
+		session = openSession();
+		t = session.beginTransaction();
+		DetachedCriteria dc3 = DetachedCriteria.forClass(Student.class, "st")
+			.createCriteria("enrolments")
+				.createCriteria("course")
+					.add( Property.forName("description").eq("Hibernate Training") )
+					.setProjection( Property.forName("st.cityState") );
+		try {
+			session.createCriteria(Enrolment.class, "e")
+				.add( Subqueries.eq( odessaWa, dc3) )
+				.list();
+			fail( "should have failed because cannot compare subquery results with multiple columns" );
+		}
+		catch ( JDBCException ex ) {
+			// expected
+		}
+		finally {
+			t.rollback();
+			session.close();
+		}
+
+		session = openSession();
+		t = session.beginTransaction();
+		session.delete(enrolment2);
+		session.delete(gavin);
+		session.delete(course);
+		t.commit();
+		session.close();
+
+	}
+
 	public void testDetachedCriteria() {
 		
 		DetachedCriteria dc = DetachedCriteria.forClass(Student.class)
@@ -511,11 +650,15 @@
 		Course course = new Course();
 		course.setCourseCode("HIB");
 		course.setDescription("Hibernate Training");
+		course.getCourseMeetings().add( new CourseMeeting( course, "Monday", 1, "1313 Mockingbird Lane" ) );
 		s.save(course);
-		
+
 		Student gavin = new Student();
 		gavin.setName("Gavin King");
 		gavin.setStudentNumber(667);
+		CityState odessaWa = new CityState( "Odessa", "WA" );
+		gavin.setCityState( odessaWa );
+		gavin.setPreferredCourse( course );
 		s.save(gavin);
 		
 		Student xam = new Student();
@@ -544,7 +687,65 @@
 		s.save(enrolment);
 		
 		s.flush();
-		
+
+		List  resultList = s.createCriteria(Enrolment.class)
+			.setProjection( Projections.projectionList()
+					.add( Property.forName( "student" ), "student" )
+					.add( Property.forName( "course" ), "course" )
+					.add( Property.forName( "semester" ), "semester" )
+					.add( Property.forName("year"), "year" )
+			)
+			.list();
+		assertEquals( 2, resultList.size() );
+		for ( Iterator it = resultList.iterator(); it.hasNext(); ) {
+			Object[] objects = ( Object[] ) it.next();
+			assertEquals( 4, objects.length );
+			assertTrue( objects[ 0 ] instanceof Student );
+			assertTrue( objects[ 1 ] instanceof Course );
+			assertTrue( objects[ 2 ] instanceof Short );
+			assertTrue( objects[ 3 ] instanceof Short );
+		}
+
+		resultList = s.createCriteria(Student.class)
+			.setProjection( Projections.projectionList()
+					.add( Projections.id().as( "studentNumber" ))
+					.add( Property.forName( "name" ), "name" )
+					.add( Property.forName( "cityState" ), "cityState" )
+					.add( Property.forName("preferredCourse"), "preferredCourse" )
+			)
+			.list();
+		assertEquals( 2, resultList.size() );
+		for ( Iterator it = resultList.iterator(); it.hasNext(); ) {
+			Object[] objects = ( Object[] ) it.next();
+			assertEquals( 4, objects.length );
+			assertTrue( objects[ 0 ] instanceof Long );
+			assertTrue( objects[ 1 ] instanceof String );
+			if ( "Gavin King".equals( objects[ 1 ] ) ) {
+				assertTrue( objects[ 2 ] instanceof CityState );
+				assertTrue( objects[ 3 ] instanceof Course );
+			}
+			else {
+				assertNull( objects[ 2 ] );
+				assertNull( objects[ 3 ] );
+			}
+		}
+
+		Object[] aResult = ( Object[] ) s.createCriteria(Student.class)
+			.add( Restrictions.idEq( new Long( 667 ) ) )
+			.setProjection( Projections.projectionList()
+					.add( Projections.id().as( "studentNumber" ))
+					.add( Property.forName( "name" ), "name" )
+					.add( Property.forName( "cityState" ), "cityState" )
+					.add( Property.forName("preferredCourse"), "preferredCourse" )
+			)
+			.uniqueResult();
+		assertNotNull( aResult );
+		assertEquals( 4, aResult.length );
+		assertTrue( aResult[ 0 ] instanceof Long );
+		assertTrue( aResult[ 1 ] instanceof String );
+		assertTrue( aResult[ 2 ] instanceof CityState );
+		assertTrue( aResult[ 3 ] instanceof Course );
+
 		Long count = (Long) s.createCriteria(Enrolment.class)
 			.setProjection( Property.forName("studentNumber").count().setDistinct() )
 			.uniqueResult();
@@ -621,7 +822,23 @@
 		StudentDTO dto = (StudentDTO) resultWithAliasedBean.get(0);
 		assertNotNull(dto.getDescription());
 		assertNotNull(dto.getName());
-	
+
+		CourseMeeting courseMeetingDto = ( CourseMeeting ) s.createCriteria(CourseMeeting.class)
+			.setProjection( Projections.projectionList()
+					.add( Property.forName("id").as("id") )
+					.add( Property.forName("course").as("course") )
+			)
+			.addOrder( Order.desc("id") )
+			.setResultTransformer( Transformers.aliasToBean(CourseMeeting.class) )
+			.uniqueResult();
+
+		assertNotNull( courseMeetingDto.getId() );
+		assertEquals( course.getCourseCode(), courseMeetingDto.getId().getCourseCode() );
+		assertEquals( "Monday", courseMeetingDto.getId().getDay() );
+		assertEquals( "1313 Mockingbird Lane", courseMeetingDto.getId().getLocation() );
+		assertEquals( 1, courseMeetingDto.getId().getPeriod() );
+		assertEquals( course.getDescription(), courseMeetingDto.getCourse().getDescription() );
+
 		s.createCriteria(Student.class)
 			.add( Restrictions.like("name", "Gavin", MatchMode.START) )
 			.addOrder( Order.asc("name") )
@@ -679,6 +896,204 @@
 		s.close();
 	}
 
+	public void testDistinctProjectionsOfComponents() {
+		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(667);
+		gavin.setCityState( new CityState( "Odessa", "WA" ) );
+		s.save(gavin);
+
+		Student xam = new Student();
+		xam.setName("Max Rydahl Andersen");
+		xam.setStudentNumber(101);
+		xam.setPreferredCourse( course );
+		xam.setCityState( new CityState( "Odessa", "WA" ) );
+		s.save(xam);
+
+		Enrolment enrolment = new Enrolment();
+		enrolment.setCourse(course);
+		enrolment.setCourseCode(course.getCourseCode());
+		enrolment.setSemester((short) 1);
+		enrolment.setYear((short) 1999);
+		enrolment.setStudent(xam);
+		enrolment.setStudentNumber(xam.getStudentNumber());
+		xam.getEnrolments().add(enrolment);
+		s.save(enrolment);
+
+		enrolment = new Enrolment();
+		enrolment.setCourse(course);
+		enrolment.setCourseCode(course.getCourseCode());
+		enrolment.setSemester((short) 3);
+		enrolment.setYear((short) 1998);
+		enrolment.setStudent(gavin);
+		enrolment.setStudentNumber(gavin.getStudentNumber());
+		gavin.getEnrolments().add(enrolment);
+		s.save(enrolment);
+
+		s.flush();
+
+		Object result = s.createCriteria( Student.class )
+			.setProjection( Projections.distinct( Property.forName( "cityState" ) ) )
+			.uniqueResult();
+		assertTrue( result instanceof CityState );
+		assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+		assertEquals( ( ( CityState ) result ).getState(), "WA" );		
+
+		result = s.createCriteria( Student.class )
+			.setProjection( Projections.distinct( Property.forName( "cityState" ).as( "cityState" ) ) )
+				.addOrder( Order.asc( "cityState" ) )
+			.uniqueResult();
+		assertTrue( result instanceof CityState );
+		assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+		assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		try {
+			result = s.createCriteria( Student.class )
+				.setProjection( Projections.count( "cityState" ) )
+				.uniqueResult();
+			fail( "should have failed with QueryException" );
+		}
+		catch ( QueryException ex ) {
+			//expected
+		}
+		finally {
+			t.rollback();
+		}
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		s.delete(gavin);
+		s.delete(xam);
+		s.delete(course);
+
+		t.commit();
+		s.close();
+	}
+
+	public void testGroupByComponent() {
+		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(667);
+		gavin.setCityState( new CityState( "Odessa", "WA" ) );
+		s.save(gavin);
+
+		Student xam = new Student();
+		xam.setName("Max Rydahl Andersen");
+		xam.setStudentNumber(101);
+		xam.setPreferredCourse( course );
+		xam.setCityState( new CityState( "Odessa", "WA" ) );
+		s.save(xam);
+
+		Enrolment enrolment = new Enrolment();
+		enrolment.setCourse(course);
+		enrolment.setCourseCode(course.getCourseCode());
+		enrolment.setSemester((short) 1);
+		enrolment.setYear((short) 1999);
+		enrolment.setStudent(xam);
+		enrolment.setStudentNumber(xam.getStudentNumber());
+		xam.getEnrolments().add(enrolment);
+		s.save(enrolment);
+
+		enrolment = new Enrolment();
+		enrolment.setCourse(course);
+		enrolment.setCourseCode(course.getCourseCode());
+		enrolment.setSemester((short) 3);
+		enrolment.setYear((short) 1998);
+		enrolment.setStudent(gavin);
+		enrolment.setStudentNumber(gavin.getStudentNumber());
+		gavin.getEnrolments().add(enrolment);
+		s.save(enrolment);
+
+		s.flush();
+
+		Object result = s.createCriteria( Student.class )
+			.setProjection( Projections.groupProperty( "cityState" ) )
+			.uniqueResult();
+		assertTrue( result instanceof CityState );
+		assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+		assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+		result = s.createCriteria( Student.class, "st")
+			.setProjection( Projections.groupProperty( "st.cityState" ) )
+			.uniqueResult();
+		assertTrue( result instanceof CityState );
+		assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+		assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+		result = s.createCriteria( Student.class, "st")
+			.setProjection( Projections.groupProperty( "st.cityState" ) )
+				.addOrder( Order.asc( "cityState" ) )
+			.uniqueResult();
+		assertTrue( result instanceof CityState );
+		assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+		assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+		result = s.createCriteria( Student.class, "st")
+			.setProjection( Projections.groupProperty( "st.cityState" ).as( "cityState" ) )
+				.addOrder( Order.asc( "cityState" ) )
+			.uniqueResult();
+		assertTrue( result instanceof CityState );
+		assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+		assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+		result = s.createCriteria( Student.class, "st")
+			.setProjection( Projections.groupProperty( "st.cityState" ).as( "cityState" ) )
+				.addOrder( Order.asc( "cityState" ) )
+			.uniqueResult();
+		assertTrue( result instanceof CityState );
+		assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+		assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+		result = s.createCriteria( Student.class, "st")
+			.setProjection( Projections.groupProperty( "st.cityState" ).as( "cityState" ) )
+			.add( Restrictions.eq( "st.cityState", new CityState( "Odessa", "WA" ) ) )
+			.addOrder( Order.asc( "cityState" ) )
+			.uniqueResult();
+		assertTrue( result instanceof CityState );
+		assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+		assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+		List list = s.createCriteria(Enrolment.class)
+			.createAlias("student", "st")
+			.createAlias("course", "co")
+			.setProjection( Projections.projectionList()
+					.add( Property.forName("co.courseCode").group() )
+					.add( Property.forName("st.cityState").group() )
+					.add( Property.forName("year").group() )
+			)
+			.list();
+
+
+		s.delete(gavin);
+		s.delete(xam);
+		s.delete(course);
+
+		t.commit();
+		s.close();
+	}
+
 	public void testRestrictionOnSubclassCollection() {
 		Session s = openSession();
 		Transaction t = s.beginTransaction();
@@ -805,6 +1220,22 @@
 		s.close();
 	}
 
+	public void testProjectedCompositeIdWithAlias() {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+
+		Course course = new Course();
+		course.setCourseCode("HIB");
+		course.setDescription("Hibernate Training");
+		course.getCourseMeetings().add( new CourseMeeting( course, "Monday", 1, "1313 Mockingbird Lane" ) );
+		s.save(course);
+		s.flush();
+
+		List data = ( List ) s.createCriteria( CourseMeeting.class).setProjection( Projections.id().as( "id" ) ).list();
+		t.rollback();
+		s.close();
+	}
+
 	public void testProjectedComponent() {
 		Session s = openSession();
 		Transaction t = s.beginTransaction();



More information about the hibernate-commits mailing list