Search code examples
javadatabasejpaormpersistence

JAVA EclipseLink optional query parameters


I have query which filters items by certain conditions:

@NamedQueries({
        @NamedQuery(
                name = ITEM.FIND_ALL_PARAMS_BY_COMPANY_COUNTRY_GROUP,
                query = "SELECT i FROM Item i where "
                        + "((i.idCompany=:companyId AND i.idEMGroup=:groupId) "
                        + "OR (i.idCompany=:companyId AND i.idEMCountry =:countryId AND i.idEMGroup is null) "
                        + "OR (i.idCompany is null AND i.idEMCountry = :countryId AND i.idEMGroup is null)) "
                        + "order by i.idEMCountry desc, i.idCompany desc, i.idEMGroup desc")
})

In some cases parameters idEMGroup o companyId can be null which generates sql looking like this IdEmCompany = 200630758) AND (IdEMGroup = NULL) and it is incorrect sql syntax is it possible to dynamically if value is null for it as 'Column IS NULL' instead of 'Column = NULL' without adding a lot of if's, or it's just better to rewrite this query using Criteria API and just check if value is present and add predicates on certain conditions ?


Solution

  • Correct answer would be to use CriteriaQuery.

    Though it is also possible to construct the query dynamically but manipulating @NamedQuery is not possible or might require stuff that makes it not worth to do.

    Instead you could construct the query first as a String and create TypedQuery by manipulating the query string

    String strQuery = "SELECT i FROM Item i"; // .. + the rest of stuff
    if(null==companyId) {
       // add something  like "companyId IS :companyId"
       // ":companyId" coulöd also be NULL"
       // but to enable using tq.setParameter("companyId", companyId)
       // without checking if there is param "companyId" so there always will
    } else {
       // add something like "companyId=:companyId"
    }
    TypedQuery<Item> tq = entityManager.createQuery(strQuery, Item.class);
    tq.setParameter("companyId", companyId);
    

    There will be some IFs but so will be in CriteriaQuery construction also.