HHH-6643 Criteria doesn't support a chaining of 2 not restrictions (sql

= not not criterion)
This commit is contained in:
Brett Meyer 2013-01-03 15:59:26 -05:00 committed by Brett Meyer
parent 03c010e519
commit bfcca64997
6 changed files with 58 additions and 9 deletions

View File

@ -25,12 +25,12 @@
package org.hibernate.criterion; package org.hibernate.criterion;
import org.hibernate.Criteria; import org.hibernate.Criteria;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.engine.spi.TypedValue; import org.hibernate.engine.spi.TypedValue;
/** /**
* Negates another criterion * Negates another criterion
* @author Gavin King * @author Gavin King
* @author Brett Meyer
*/ */
public class NotExpression implements Criterion { public class NotExpression implements Criterion {
@ -40,14 +40,9 @@ public class NotExpression implements Criterion {
this.criterion = criterion; this.criterion = criterion;
} }
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
throws HibernateException { return criteriaQuery.getFactory().getDialect().getNotExpression(
if ( criteriaQuery.getFactory().getDialect() instanceof MySQLDialect ) { criterion.toSqlString( criteria, criteriaQuery ) );
return "not (" + criterion.toSqlString(criteria, criteriaQuery) + ')';
}
else {
return "not " + criterion.toSqlString(criteria, criteriaQuery);
}
} }
public TypedValue[] getTypedValues( public TypedValue[] getTypedValues(

View File

@ -2381,4 +2381,8 @@ public abstract class Dialect implements ConversionContext {
public boolean supportsNotNullUnique() { public boolean supportsNotNullUnique() {
return true; return true;
} }
public String getNotExpression( String expression ) {
return "not " + expression;
}
} }

View File

@ -415,4 +415,9 @@ public class MySQLDialect extends Dialect {
} }
}; };
} }
@Override
public String getNotExpression( String expression ) {
return "not (" + expression + ")";
}
} }

View File

@ -581,4 +581,9 @@ public class Oracle8iDialect extends Dialect {
public boolean useFollowOnLocking() { public boolean useFollowOnLocking() {
return true; return true;
} }
@Override
public String getNotExpression( String expression ) {
return "not (" + expression + ")";
}
} }

View File

@ -377,4 +377,9 @@ public class Oracle9Dialect extends Dialect {
public int getInExpressionCountLimit() { public int getInExpressionCountLimit() {
return PARAM_LIST_SIZE_LIMIT; return PARAM_LIST_SIZE_LIMIT;
} }
@Override
public String getNotExpression( String expression ) {
return "not (" + expression + ")";
}
} }

View File

@ -2012,5 +2012,40 @@ public class CriteriaQueryTest extends BaseCoreFunctionalTestCase {
} }
@Test
@TestForIssue( jiraKey = "HHH-6643" )
public void testNotNot() {
Student student1 = new Student();
student1.setName("Foo1 Foo1");
student1.setStudentNumber(1);
Student student2 = new Student();
student2.setName("Foo2 Foo2");
student2.setStudentNumber(2);
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist( student1 );
s.persist( student2 );
s.flush();
s.clear();
// Although this example is simplified and the "not not" is pointless,
// double negatives can occur in some dynamic applications (regardless
// if it results from bad design or not). Test to ensure the dialect
// handles them as expected.
List<Student> students = s.createCriteria( Student.class ).add(
Restrictions.not(
Restrictions.not(
Restrictions.eq( "studentNumber", 1l ) ) )
).list();
assertEquals( students.size(), 1 );
assertEquals( students.get( 0 ).getStudentNumber(), 1 );
t.commit();
session.close();
}
} }