Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular expression matching in queryDSL

Tags:

jpa

querydsl

I'm trying to do a query in order to reproduce the following in SQL:

where REGEXP_LIKE(variable, regular_expression);

I tried to use the match predicate and the MATCH operator but it seems that in both cases, the expression is converted to a like by com.mysema.query.types.ExpressionUtils#regexToLike.

The regexToLike method would reject any '*' or '[' corresponding to a regex syntax and would throw a QueryException :

'12-*34' can't be converted to like form"

Is there any way to do this on QueryDSL ?

EDIT : The databse is Oracle 11G

The querydsl library used is : com.mysema.querydsl version 3.6.9

I shall try again after migrating to com.querydsl 's latest version (4) as sson as spring data 1.12 is released (querydsl 4 support).

Here is the relevant code :

String telRegex = "";
            if (this.tel.length() > 1)
            {
                char[] chars = this.tel.toCharArray();
                telRegex += chars[0];
                for (int i = 1; i < chars.length; i++)
                {
                    // NB can't make regex to work as special characters are banned cf. ExpressionUtils.regexToLike
                    //telRegex += "-*" + chars[i];
                    telRegex += "" + chars[i];
                }
            }
            else
            {
                telRegex = rechercheDto.getTelephone();
            }

            telRegex = "^" + telRegex + "$";

            // query
            predicate.and($(contact.getTel()).isNotNull())
            .and(
                $(contact.getTel()).matches(telRegex )
            );
like image 464
Laurent B Avatar asked Oct 16 '25 18:10

Laurent B


2 Answers

to do a WHERE clause using a REXGEP expression, I use the following code

jpaQuery 
  = jpaQuery
      .where
        (Expressions.booleanTemplate
          ("function('REGEXP_LIKE',{0},{1}"
          ,qTable.ctcTireLineName
          ,sRegex
          )
        );

I use QueryDSL 3.7.2.

I have just tried using sRegex = "^(EA|SPORT).*" and it work fine in Java 8.

like image 163
schlebe Avatar answered Oct 19 '25 09:10

schlebe


Pattern matching in JPA queries is done with LIKE and is limited only to % and _. Query DSL will try to convert your regular expression into a LIKE expression.

From documentation on StringExpression.matches(String)

Some implementations such as Querydsl JPA will try to convert a regex expression into like form and will throw an Exception when this fails

like image 31
Luka Klepec Avatar answered Oct 19 '25 08:10

Luka Klepec