Home > Net >  Build WHERE clause dynamically based on filter in queryDSL
Build WHERE clause dynamically based on filter in queryDSL

Time:12-18

I have a query that needs a dynamic SQL WHERE clauses based on filters.

Issue

It may give me a NullPointerException (NPE) if I'm adding an "AND" while the previous filter is not existing.

Code

public List<BlocageDeblocageCompte> getMyQuery(FiltersDTO filters) {

    JPAQuery<MY_ENTITY> myEntity = getJPAQueryFactory().selectFrom(myEntity).limit(20);
    BooleanExpression whereClause = null;

    boolean whereClauseAdded = false;
    boolean ifNoFilter = Stream.of(myEntity).allMatch(Objects::isNull);

    if (ifNoFilter) {
        return new ArrayList<>(myEntity.fetchAll().fetch());
    }
            
    if (filters.getId() != null) {
        whereClause = myEntity.id.eq(filters.getId());
        whereClauseAdded = true;
    }

    if (filters.getName() != null) {
        if (whereClauseAdded) {
            whereClause = whereClause.and(myEntity.id.eq(filters.getName()));
        } else {
            whereClause = myEntity.id.eq(filters.getName());
            whereClauseAdded = true;
        }
    }

    // remaining code
}

Question

Is there a better way to add the filters, without risking a NPE?

CodePudding user response:

To construct complex boolean queries like this you can use com.querydsl.core.BooleanBuilder:

public List<MyEntity> getMyQuery(FiltersDTO filters) {
    MyEntity myEntity = QModel.myEntity;

    // build an optional WHERE clause with predicates using AND conjunctions 
    BooleanBuilder builder = new BooleanBuilder();

    if (filters.getId() != null) {
        builder.and(myEntity.id.eq(filters.getId()));   
    }
    
    if (filters.getName() != null) {
        builder.and(myEntity.id.eq(filters.getName()));   
    }
    
    // construct the query
    return getJPAQueryFactory().selectFrom(myEntity)
        .limit(20)
        .where(builder)  // myEntity.id eq id1 AND myEntity.name eq name1
        .fetch();            
}

See also

Similar questions:

References:

CodePudding user response:

you can use Specification in JPA:here is the link that i used myself

https://www.baeldung.com/rest-api-search-language-spring-data-specifications

CodePudding user response:

I found out a simple solution, when we do WHERE on all of them it transform automatically the second where to AND. thank u guys.

    JPAQuery<MyEntity> myEntityJPAQUERY=
            getJPAQueryFactory()
                    .selectFrom(QmyEntity);
    
    if (filtresDTO.getId() != null) {
        myEntityJPAQUERY=myEntityJPAQUERY.where(QmyEntity.id.eq(ffiltresDTO.getId()));

    if (filtresDTO.getName() != null) {
myEntityJPAQUERY=myEntityJPAQUERY.where(QmyEntity.name.eq(ffiltresDTO.getName()))
    }
  • Related