diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Restrictions.java b/hibernate-core/src/main/java/org/hibernate/criterion/Restrictions.java index 6c1b4b8c7d..6530588357 100755 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Restrictions.java +++ b/hibernate-core/src/main/java/org/hibernate/criterion/Restrictions.java @@ -91,6 +91,7 @@ public class Restrictions { public static SimpleExpression like(String propertyName, String value, MatchMode matchMode) { return new SimpleExpression(propertyName, matchMode.toMatchString(value), " like " ); } + /** * A case-insensitive "like", similar to Postgres ilike * operator @@ -111,8 +112,12 @@ public class Restrictions { * @return Criterion */ public static Criterion ilike(String propertyName, Object value) { - return new LikeExpression(propertyName, value.toString()); + if ( value == null ) { + throw new IllegalArgumentException( "Comparison value passed to ilike cannot be null" ); + } + return ilike( propertyName, value.toString(), MatchMode.ANYWHERE ); } + /** * Apply a "greater than" constraint to the named property * @param propertyName diff --git a/hibernate-core/src/test/java/org/hibernate/test/criterion/CriterionTest.java b/hibernate-core/src/test/java/org/hibernate/test/criterion/CriterionTest.java new file mode 100644 index 0000000000..f95cca09aa --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/criterion/CriterionTest.java @@ -0,0 +1,117 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.criterion; + +import org.hibernate.Criteria; +import org.hibernate.HibernateException; +import org.hibernate.IrrelevantEntity; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.Configuration; +import org.hibernate.criterion.CriteriaQuery; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.LikeExpression; +import org.hibernate.criterion.Restrictions; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.TypedValue; +import org.hibernate.internal.CriteriaImpl; +import org.hibernate.loader.criteria.CriteriaQueryTranslator; +import org.hibernate.type.Type; + +import org.junit.Test; + +import org.hibernate.testing.junit4.BaseUnitTestCase; + +import static org.junit.Assert.assertEquals; + +/** + * @author Steve Ebersole + */ +public class CriterionTest extends BaseUnitTestCase { + @Test + public void testIlikeRendering() { + SessionFactory sf = new Configuration() + .addAnnotatedClass( IrrelevantEntity.class ) + .setProperty( AvailableSettings.DIALECT, IlikeSupportingDialect.class.getName() ) + .buildSessionFactory(); + final Criteria criteria = sf.openSession().createCriteria( IrrelevantEntity.class ); + final CriteriaQueryTranslator translator = new CriteriaQueryTranslator( + (SessionFactoryImplementor) sf, + (CriteriaImpl) criteria, + IrrelevantEntity.class.getName(), + "a" + ); + final Criterion ilikeExpression = Restrictions.ilike( "name", "abc" ); + final String ilikeExpressionSqlFragment = ilikeExpression.toSqlString( criteria, translator ); + assertEquals( "a.name insensitiveLike ?", ilikeExpressionSqlFragment ); + } + + @Test + public void testIlikeMimicing() { + SessionFactory sf = new Configuration() + .addAnnotatedClass( IrrelevantEntity.class ) + .setProperty( AvailableSettings.DIALECT, NonIlikeSupportingDialect.class.getName() ) + .buildSessionFactory(); + final Criteria criteria = sf.openSession().createCriteria( IrrelevantEntity.class ); + final CriteriaQueryTranslator translator = new CriteriaQueryTranslator( + (SessionFactoryImplementor) sf, + (CriteriaImpl) criteria, + IrrelevantEntity.class.getName(), + "a" + ); + final Criterion ilikeExpression = Restrictions.ilike( "name", "abc" ); + final String ilikeExpressionSqlFragment = ilikeExpression.toSqlString( criteria, translator ); + assertEquals( "lowLowLow(a.name) like ?", ilikeExpressionSqlFragment ); + } + + public static class IlikeSupportingDialect extends Dialect { + @Override + public boolean supportsCaseInsensitiveLike() { + return true; + } + + @Override + public String getCaseInsensitiveLike() { + return "insensitiveLike"; + } + } + + public static class NonIlikeSupportingDialect extends Dialect { + @Override + public boolean supportsCaseInsensitiveLike() { + return false; + } + + @Override + public String getCaseInsensitiveLike() { + throw new UnsupportedOperationException(); + } + + @Override + public String getLowercaseFunction() { + return "lowLowLow"; + } + } +}