Search code examples
javahibernatejakarta-eeormhibernate-criteria

Hibernate criteria accepting %% value


I am using the below Hibernate code to filter workFlowName.

crt.add(Restrictions.like("workFlowName", workFlow, MatchMode.ANYWHERE));
// crt is the criteria

The problem is when I pass the value to workFlow from web (TextBox).it fetching the value correctly (I am passing sym in text box if fetch 10 records.if i pass the same value like %sym% again it is fetching same record).

Whether the criteria will omit when it see %% as argument?


Solution

  • Hibernate does not escape special chars in like (e.g. the percentage % sign). But there are descriptions how to solve it (escape it):

    In general we could implement our own EscapedILikeExpression (taken from the first link above)

    class EscapedILikeExpression extends IlikeExpression {
        private static final String HIBERNATE_ESCAPE_CHAR = "\\";
    
        public EscapedILikeExpression(String propertyName, Object value) {
            super(propertyName, value);
        }
    
        public EscapedILikeExpression(String propertyName, String value, MatchMode matchMode) {
            super(propertyName, replaceAll(value), matchMode);
        }
    
        private static String replaceAll(String value) {
            return value
                    .replace("\\",  HIBERNATE_ESCAPE_CHAR + "\\")
                    .replace("_",   HIBERNATE_ESCAPE_CHAR + "_")
                    .replace("%",   HIBERNATE_ESCAPE_CHAR + "%");
    
        }
    }
    

    and

    public class EscapedRestrictions {
        public static Criterion ilike(String propertyName, String value) {
            return new EscapedILikeExpression(propertyName, value);
        }
    
        public static Criterion ilike(String propertyName, String value, MatchMode matchMode) {
            return new EscapedILikeExpression(propertyName, value, matchMode);
        }
    }
    

    And now we should be able to call

    crt.add(EscapedRestrictions.ilike("workFlowName", workFlow, MatchMode.ANYWHERE));