[hibernate-commits] Hibernate SVN: r19317 - in core/branches/Branch_3_5: parent and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Apr 28 13:19:20 EDT 2010


Author: gbadner
Date: 2010-04-28 13:19:19 -0400 (Wed, 28 Apr 2010)
New Revision: 19317

Modified:
   core/branches/Branch_3_5/core/src/main/java/org/hibernate/criterion/CountProjection.java
   core/branches/Branch_3_5/parent/pom.xml
   core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
   core/branches/Branch_3_5/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/branches/Branch_3_5/core/src/main/java/org/hibernate/criterion/CountProjection.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/criterion/CountProjection.java	2010-04-28 16:25:52 UTC (rev 19316)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/criterion/CountProjection.java	2010-04-28 17:19:19 UTC (rev 19317)
@@ -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/branches/Branch_3_5/parent/pom.xml
===================================================================
--- core/branches/Branch_3_5/parent/pom.xml	2010-04-28 16:25:52 UTC (rev 19316)
+++ core/branches/Branch_3_5/parent/pom.xml	2010-04-28 17:19:19 UTC (rev 19317)
@@ -953,6 +953,26 @@
             </properties>
         </profile>
 
+        <profile>
+            <id>mysql5-gbadner</id>
+            <dependencies>
+                <dependency>
+                    <groupId>mysql</groupId>
+                    <artifactId>mysql-connector-java</artifactId>
+                    <version>5.0.5</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.MySQL5InnoDBDialect</db.dialect>
+                <jdbc.driver>com.mysql.jdbc.Driver</jdbc.driver>
+                <jdbc.url>jdbc:mysql://localhost/test</jdbc.url>
+                <jdbc.user>root</jdbc.user>
+                <jdbc.pass></jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
     </profiles>
 
     <properties>

Modified: core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
===================================================================
--- core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java	2010-04-28 16:25:52 UTC (rev 19316)
+++ core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java	2010-04-28 17:19:19 UTC (rev 19317)
@@ -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/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java
===================================================================
--- core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java	2010-04-28 16:25:52 UTC (rev 19316)
+++ core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java	2010-04-28 17:19:19 UTC (rev 19317)
@@ -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