[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