[hibernate-commits] Hibernate SVN: r19319 - in core/trunk: testsuite/src/test/java/org/hibernate/test/criteria and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Apr 28 13:54:43 EDT 2010


Author: gbadner
Date: 2010-04-28 13:54:43 -0400 (Wed, 28 Apr 2010)
New Revision: 19319

Modified:
   core/trunk/core/src/main/java/org/hibernate/criterion/CountProjection.java
   core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
   core/trunk/testsuite/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java
Log:
HHH-4957 HHH-3096 : Fix COUNT( DISTINCT ...) for single and multiple arguments

Modified: core/trunk/core/src/main/java/org/hibernate/criterion/CountProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/CountProjection.java	2010-04-28 17:24:31 UTC (rev 19318)
+++ core/trunk/core/src/main/java/org/hibernate/criterion/CountProjection.java	2010-04-28 17:54:43 UTC (rev 19319)
@@ -23,6 +23,14 @@
  */
 package org.hibernate.criterion;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.hibernate.Criteria;
+import org.hibernate.QueryException;
+
 /**
  * A count
  * @author Gavin King
@@ -43,6 +51,18 @@
 		}
 	}
 
+	protected List buildFunctionParameterList(Criteria criteria, CriteriaQuery criteriaQuery) {
+		String cols[] = criteriaQuery.getColumns( propertyName, criteria );
+		return ( distinct ? buildCountDistinctParameterList( cols ) : Arrays.asList( cols ) );
+	}
+
+	private List buildCountDistinctParameterList(String[] cols) {
+		List params = new ArrayList( cols.length + 1 );
+		params.add( "distinct" );
+		params.addAll( Arrays.asList( cols ) );
+		return params;
+	}
+
 	public CountProjection setDistinct() {
 		distinct = true;
 		return this;

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-28 17:24:31 UTC (rev 19318)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java	2010-04-28 17:54:43 UTC (rev 19319)
@@ -27,6 +27,8 @@
 import org.hibernate.criterion.Property;
 import org.hibernate.criterion.Restrictions;
 import org.hibernate.criterion.Subqueries;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.exception.SQLGrammarException;
 import org.hibernate.junit.functional.FunctionalTestCase;
 import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
 import org.hibernate.test.hql.Animal;
@@ -515,6 +517,16 @@
 			.uniqueResult();
 		assertEquals(count, new Long(2));
 		
+		count = (Long) s.createCriteria(Enrolment.class)
+			.setProjection( Projections.countDistinct("studentNumber") )
+			.uniqueResult();
+		assertEquals(count, new Long(2));
+
+		count = (Long) s.createCriteria(Enrolment.class)
+			.setProjection( Projections.countDistinct("courseCode").as( "cnt" ) )
+			.uniqueResult();
+		assertEquals(count, new Long(1));
+
 		Object object = s.createCriteria(Enrolment.class)
 			.setProjection( Projections.projectionList()
 					.add( Projections.count("studentNumber") )
@@ -955,6 +967,15 @@
 		assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
 		assertEquals( ( ( CityState ) result ).getState(), "WA" );
 
+		result = s.createCriteria( Student.class )
+			.setProjection( Projections.count( "cityState.city" ) )
+			.uniqueResult();
+		assertEquals( 2, ( ( Long ) result ).longValue() );
+
+		result = s.createCriteria( Student.class )
+			.setProjection( Projections.countDistinct( "cityState.city" ) )
+			.uniqueResult();
+		assertEquals( 1, ( ( Long ) result ).longValue() );
 		t.commit();
 		s.close();
 
@@ -964,18 +985,37 @@
 			result = s.createCriteria( Student.class )
 				.setProjection( Projections.count( "cityState" ) )
 				.uniqueResult();
-			fail( "should have failed with QueryException" );
+			fail( "expected SQLGrammarException" );
 		}
-		catch ( QueryException ex ) {
-			//expected
+		catch ( SQLGrammarException ex ) {
+			// expected
 		}
 		finally {
 			t.rollback();
+			s.close();
 		}
-		s.close();
 
 		s = openSession();
 		t = s.beginTransaction();
+		try {
+			result = s.createCriteria( Student.class )
+				.setProjection( Projections.countDistinct( "cityState" ) )
+				.uniqueResult();
+			assertEquals( 1, ( ( Long ) result ).longValue() );
+		}
+		catch ( SQLGrammarException ex ) {
+			// HSQLDB's cannot handle more than 1 argument in SELECT COUNT( DISTINCT ... ) )
+			if ( ! ( getDialect() instanceof HSQLDialect ) )  {
+				throw ex;
+			}
+		}
+		finally {
+			t.rollback();
+			s.close();
+		}
+
+		s = openSession();
+		t = s.beginTransaction();
 		s.delete(gavin);
 		s.delete(xam);
 		s.delete(course);
@@ -1214,10 +1254,46 @@
 		course.getCourseMeetings().add( new CourseMeeting( course, "Monday", 1, "1313 Mockingbird Lane" ) );
 		s.save(course);
 		s.flush();
-
+		s.clear();
 		List data = ( List ) s.createCriteria( CourseMeeting.class).setProjection( Projections.id() ).list();
-		t.rollback();
+		t.commit();
 		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		try {
+			s.createCriteria( CourseMeeting.class).setProjection( Projections.count( "id" ) ).list();
+			fail( "should have thrown SQLGrammarException" );
+		}
+		catch ( SQLGrammarException ex ) {
+			// expected
+		}
+		finally {
+			t.rollback();
+			s.close();
+		}
+
+		s = openSession();
+		t = s.beginTransaction();
+		try {
+			Object result = s.createCriteria( CourseMeeting.class).setProjection( Projections.countDistinct( "id" ) ).list();
+		}
+		catch ( SQLGrammarException ex ) {
+			// HSQLDB's cannot handle more than 1 argument in SELECT COUNT( DISTINCT ... ) )
+			if ( ! ( getDialect() instanceof HSQLDialect ) )  {
+				throw ex;
+			}
+		}
+		finally {
+			t.rollback();
+			s.close();
+		}
+
+		s = openSession();
+		t = s.beginTransaction();
+		s.delete( course );
+		t.commit();
+		s.close();
 	}
 
 	public void testProjectedCompositeIdWithAlias() {

Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java	2010-04-28 17:24:31 UTC (rev 19318)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java	2010-04-28 17:54:43 UTC (rev 19319)
@@ -8,6 +8,10 @@
 import junit.framework.Test;
 
 import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.Transaction;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.exception.SQLGrammarException;
 import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
 import org.hibernate.classic.Session;
 import org.hibernate.criterion.Projections;
@@ -171,4 +175,140 @@
 		s.close();
 	}
 
+	public void testCountReturnValues() {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Human human1 = new Human();
+		human1.setName( new Name( "John", 'Q', "Public" ) );
+		human1.setNickName( "Johnny" );
+		s.save(human1);
+		Human human2 = new Human();
+		human2.setName( new Name( "John", 'A', "Doe" ) );
+		human2.setNickName( "Johnny" );
+		s.save( human2 );
+		Human human3 = new Human();
+		human3.setName( new Name( "John", 'A', "Doe" ) );
+		human3.setNickName( "Jack" );
+		s.save( human3 );
+		Human human4 = new Human();
+		human4.setName( new Name( "John", 'A', "Doe" ) );
+		s.save( human4 );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+
+		Long count = ( Long ) s.createQuery( "select count( * ) from Human" ).uniqueResult();
+		assertEquals( 4, count.longValue() );
+		s.clear();
+		count = ( Long ) s.createCriteria( Human.class )
+				.setProjection( Projections.rowCount() )
+				.uniqueResult();
+		assertEquals( 4, count.longValue() );
+		s.clear();
+
+		count = ( Long ) s.createQuery( "select count( nickName ) from Human" ).uniqueResult();
+		assertEquals( 3, count.longValue() );
+		s.clear();
+		count = ( Long ) s.createCriteria( Human.class )
+				.setProjection( Projections.count( "nickName" ) )
+				.uniqueResult();
+		assertEquals( 3, count.longValue() );
+		s.clear();
+
+		count = ( Long ) s.createQuery( "select count( distinct nickName ) from Human" ).uniqueResult();
+		assertEquals( 2, count.longValue() );
+		s.clear();
+		count = ( Long ) s.createCriteria( Human.class )
+				.setProjection( Projections.count( "nickName" ).setDistinct() )
+				.uniqueResult();
+		assertEquals( 2, count.longValue() );
+		s.clear();
+
+		s = openSession();
+		t = s.beginTransaction();
+		try {
+			count = ( Long ) s.createQuery( "select count( distinct name ) from Human" ).uniqueResult();
+			assertEquals( 2, count.longValue() );
+		}
+		catch ( SQLGrammarException ex ) {
+			// HSQLDB's cannot handle more than 1 argument in SELECT COUNT( DISTINCT ... ) )
+			if ( ! ( getDialect() instanceof HSQLDialect ) )  {
+				throw ex;
+			}
+		}
+		finally {
+			t.rollback();
+			s.close();
+		}
+
+		s = openSession();
+		t = s.beginTransaction();
+		try {
+			count = ( Long ) s.createCriteria( Human.class )
+				.setProjection( Projections.count( "name" ).setDistinct() )
+				.uniqueResult();
+			assertEquals( 2, count.longValue() );
+		}
+		catch ( SQLGrammarException ex ) {
+			// HSQLDB's cannot handle more than 1 argument in SELECT COUNT( DISTINCT ... ) )
+			if ( ! ( getDialect() instanceof HSQLDialect ) )  {
+				throw ex;
+			}
+		}
+		finally {
+			t.rollback();
+			s.close();
+		}
+
+		s = openSession();
+		t = s.beginTransaction();
+		count = ( Long ) s.createQuery( "select count( distinct name.first ) from Human" ).uniqueResult();
+		assertEquals( 1, count.longValue() );
+		s.clear();
+		count = ( Long ) s.createCriteria( Human.class )
+				.setProjection( Projections.count( "name.first" ).setDistinct() )
+				.uniqueResult();
+		assertEquals( 1, count.longValue() );
+		t.commit();
+		s.close();
+
+		s = openSession();
+		t = s.beginTransaction();
+		try {
+			count = ( Long ) s.createQuery( "select count( name ) from Human" ).uniqueResult();
+			fail( "should have failed due to SQLGrammarException" );
+		}
+		catch ( SQLGrammarException ex ) {
+			// expected
+		}
+		finally {
+			t.rollback();
+			s.close();
+		}
+
+		s = openSession();
+		t = s.beginTransaction();
+		try {
+			count = ( Long ) s.createCriteria( Human.class )
+				.setProjection( Projections.count( "name" ) )
+				.uniqueResult();
+			fail( "should have failed due to SQLGrammarException" );
+		}
+		catch ( SQLGrammarException ex ) {
+			// expected
+		}
+		finally {
+			t.rollback();
+			s.close();
+		}
+
+		s = openSession();
+		t = s.beginTransaction();
+		s.createQuery( "delete from Human" ).executeUpdate();
+		t.commit();
+		s.close();
+	}
+
 }



More information about the hibernate-commits mailing list