Search code examples
jpaspring-dataquerydsljpa-criteria

Query creation using dynamic filter map in QueryDSL and spring data JPA


I am using Spring Data and JPA in my application and I am trying to implement QueryDSL for dynamic criteria API. As far as if I send specific values in criteria, it works fine using below predicate:

Predicate predicate = QProductInfo.productInfo.shopName.eq(shopName).and(QProductInfo.productInfo.productType.eq(productType));

But if I receive multiple filter parameters and want to use a Map to store key-value pair of (column_name - column_value) to derive query dynamically, I am not able to create query for the same. Means I know I can add as many condition using and or other operator in Predicate but exactly how many expression I need to use is decided only at run time so not able to figure out the way to form right expression.

Here is some code information

@Entity
Public class ProductInfo{
productId;
title;
vendor;
code;
.... and more
}

Now filter can vary from 1 to n fields with values like filter 1 = product_id=123,title=test filter 2 =title= xyz, code= abc, vendor=pqr

So I will use map to store key-value pair(title-xyz and so on) and would like to construct query dynamically.

I went through many tutorial but could not find appropriate solution so far for my conditions. I thought of using Switch also while iterating loop for map, but how to club all expressions/predicates, I am not getting any idea.

If I don't find solution, probably I will use JPA Criteria API where we can use List of Predicates easily. Let me know if any information required to help me here.

Thanks


Solution

  • I could able to fix my issue with following steps: I used BooleanBuilder and PathBuilder.

    Here is snippet of code:

    BooleanBuilder builder = new BooleanBuilder();
    PathBuilder<ProductInfo> path = new PathBuilder<>(ProductInfo.class, "productInfo");
        if(criteriaMap != null && !criteriaMap.isEmpty()) {
            for (Map.Entry<String, String> entry : criteriaMap.entrySet()) {
                builder.and(path.getString(entry.getKey()).eq(entry.getValue()));    
            }
        }
    

    Here builder manage to add entries from Map (which gives column name and value in form of key-value pair) and PathBuilder is used to set column name as parameter.

    By using it, we can use QueryDSL efficiently for creating dynamic query.

    Thanks