Example usage for javax.persistence.criteria CriteriaBuilder and

List of usage examples for javax.persistence.criteria CriteriaBuilder and

Introduction

In this page you can find the example usage for javax.persistence.criteria CriteriaBuilder and.

Prototype

Predicate and(Expression<Boolean> x, Expression<Boolean> y);

Source Link

Document

Create a conjunction of the given boolean expressions.

Usage

From source file:ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.java

private Set<Long> addPredicateNumber(String theParamName, Set<Long> thePids,
        List<? extends IQueryParameterType> theList) {
    if (theList == null || theList.isEmpty()) {
        return thePids;
    }//  w  w  w . ja  va 2 s .c  o  m

    CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
    CriteriaQuery<Long> cq = builder.createQuery(Long.class);
    Root<ResourceIndexedSearchParamNumber> from = cq.from(ResourceIndexedSearchParamNumber.class);
    cq.select(from.get("myResourcePid").as(Long.class));

    List<Predicate> codePredicates = new ArrayList<Predicate>();
    for (IQueryParameterType nextOr : theList) {
        IQueryParameterType params = nextOr;

        if (params instanceof NumberParam) {
            NumberParam param = (NumberParam) params;

            BigDecimal value = param.getValue();
            if (value == null) {
                return thePids;
            }

            Path<Object> fromObj = from.get("myValue");
            if (param.getComparator() == null) {
                double mul = value.doubleValue() * 1.01;
                double low = value.doubleValue() - mul;
                double high = value.doubleValue() + mul;
                Predicate lowPred = builder.ge(fromObj.as(Long.class), low);
                Predicate highPred = builder.le(fromObj.as(Long.class), high);
                codePredicates.add(builder.and(lowPred, highPred));
            } else {
                switch (param.getComparator()) {
                case GREATERTHAN:
                    codePredicates.add(builder.greaterThan(fromObj.as(BigDecimal.class), value));
                    break;
                case GREATERTHAN_OR_EQUALS:
                    codePredicates.add(builder.ge(fromObj.as(BigDecimal.class), value));
                    break;
                case LESSTHAN:
                    codePredicates.add(builder.lessThan(fromObj.as(BigDecimal.class), value));
                    break;
                case LESSTHAN_OR_EQUALS:
                    codePredicates.add(builder.le(fromObj.as(BigDecimal.class), value));
                    break;
                }
            }
        } else {
            throw new IllegalArgumentException("Invalid token type: " + params.getClass());
        }

    }

    Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));

    Predicate type = builder.equal(from.get("myResourceType"), myResourceName);
    Predicate name = builder.equal(from.get("myParamName"), theParamName);
    if (thePids.size() > 0) {
        Predicate inPids = (from.get("myResourcePid").in(thePids));
        cq.where(builder.and(type, name, masterCodePredicate, inPids));
    } else {
        cq.where(builder.and(type, name, masterCodePredicate));
    }

    TypedQuery<Long> q = myEntityManager.createQuery(cq);
    return new HashSet<Long>(q.getResultList());
}

From source file:ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.java

private Predicate addPredicateDateFromRange(CriteriaBuilder theBuilder,
        From<ResourceIndexedSearchParamDate, ResourceIndexedSearchParamDate> theFrom, DateRangeParam theRange) {
    Date lowerBound = theRange.getLowerBoundAsInstant();
    Date upperBound = theRange.getUpperBoundAsInstant();

    Predicate lb = null;//w  w w  .  j  a v a  2 s.c  om
    if (lowerBound != null) {
        Predicate gt = theBuilder.greaterThanOrEqualTo(theFrom.<Date>get("myValueLow"), lowerBound);
        Predicate lt = theBuilder.greaterThanOrEqualTo(theFrom.<Date>get("myValueHigh"), lowerBound);
        lb = theBuilder.or(gt, lt);

        // Predicate gin = builder.isNull(from.get("myValueLow"));
        // Predicate lbo = builder.or(gt, gin);
        // Predicate lin = builder.isNull(from.get("myValueHigh"));
        // Predicate hbo = builder.or(lt, lin);
        // lb = builder.and(lbo, hbo);
    }

    Predicate ub = null;
    if (upperBound != null) {
        Predicate gt = theBuilder.lessThanOrEqualTo(theFrom.<Date>get("myValueLow"), upperBound);
        Predicate lt = theBuilder.lessThanOrEqualTo(theFrom.<Date>get("myValueHigh"), upperBound);
        ub = theBuilder.or(gt, lt);

        // Predicate gin = builder.isNull(from.get("myValueLow"));
        // Predicate lbo = builder.or(gt, gin);
        // Predicate lin = builder.isNull(from.get("myValueHigh"));
        // Predicate ubo = builder.or(lt, lin);
        // ub = builder.and(ubo, lbo);

    }

    if (lb != null && ub != null) {
        return (theBuilder.and(lb, ub));
    } else if (lb != null) {
        return (lb);
    } else {
        return (ub);
    }
}

From source file:ca.uhn.fhir.jpa.dao.SearchBuilder.java

private Predicate createPredicateNumeric(CriteriaBuilder builder, IQueryParameterType params,
        ParamPrefixEnum cmpValue, BigDecimal valueValue, final Expression<BigDecimal> path,
        String invalidMessageName, String theValueString) {
    Predicate num;//from   w w  w  .  j a v a  2  s  .c o m
    switch (cmpValue) {
    case GREATERTHAN:
        num = builder.gt(path, valueValue);
        break;
    case GREATERTHAN_OR_EQUALS:
        num = builder.ge(path, valueValue);
        break;
    case LESSTHAN:
        num = builder.lt(path, valueValue);
        break;
    case LESSTHAN_OR_EQUALS:
        num = builder.le(path, valueValue);
        break;
    case APPROXIMATE:
    case EQUAL:
    case NOT_EQUAL:
        BigDecimal mul = calculateFuzzAmount(cmpValue, valueValue);
        BigDecimal low = valueValue.subtract(mul, MathContext.DECIMAL64);
        BigDecimal high = valueValue.add(mul, MathContext.DECIMAL64);
        Predicate lowPred;
        Predicate highPred;
        if (cmpValue != ParamPrefixEnum.NOT_EQUAL) {
            lowPred = builder.ge(path.as(BigDecimal.class), low);
            highPred = builder.le(path.as(BigDecimal.class), high);
            num = builder.and(lowPred, highPred);
            ourLog.trace("Searching for {} <= val <= {}", low, high);
        } else {
            // Prefix was "ne", so reverse it!
            lowPred = builder.lt(path.as(BigDecimal.class), low);
            highPred = builder.gt(path.as(BigDecimal.class), high);
            num = builder.or(lowPred, highPred);
        }
        break;
    default:
        String msg = myContext.getLocalizer().getMessage(SearchBuilder.class, invalidMessageName,
                cmpValue.getValue(), params.getValueAsQueryToken(myContext));
        throw new InvalidRequestException(msg);
    }
    return num;
}

From source file:ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.java

private Predicate createPredicateString(IQueryParameterType theParameter, String theParamName,
        CriteriaBuilder theBuilder,
        From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> theFrom) {
    String rawSearchTerm;//from  w w w . j  a v a  2 s .  c o  m
    if (theParameter instanceof TokenParam) {
        TokenParam id = (TokenParam) theParameter;
        if (!id.isText()) {
            throw new IllegalStateException("Trying to process a text search on a non-text token parameter");
        }
        rawSearchTerm = id.getValue();
    } else if (theParameter instanceof StringParam) {
        StringParam id = (StringParam) theParameter;
        rawSearchTerm = id.getValue();
    } else if (theParameter instanceof IPrimitiveDatatype<?>) {
        IPrimitiveDatatype<?> id = (IPrimitiveDatatype<?>) theParameter;
        rawSearchTerm = id.getValueAsString();
    } else {
        throw new IllegalArgumentException("Invalid token type: " + theParameter.getClass());
    }

    if (rawSearchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
        throw new InvalidRequestException("Parameter[" + theParamName + "] has length ("
                + rawSearchTerm.length() + ") that is longer than maximum allowed ("
                + ResourceIndexedSearchParamString.MAX_LENGTH + "): " + rawSearchTerm);
    }

    String likeExpression = normalizeString(rawSearchTerm);
    likeExpression = likeExpression.replace("%", "[%]") + "%";

    Predicate singleCode = theBuilder.like(theFrom.get("myValueNormalized").as(String.class), likeExpression);
    if (theParameter instanceof StringParam && ((StringParam) theParameter).isExact()) {
        Predicate exactCode = theBuilder.equal(theFrom.get("myValueExact"), rawSearchTerm);
        singleCode = theBuilder.and(singleCode, exactCode);
    }
    return singleCode;
}

From source file:aode.lx.persistence.DynamicSpecifications.java

public static <T> Specification<T> bySearchFilter(final Collection<SearchFilter> filters,
        final Class<T> entityClazz) {
    return new Specification<T>() {
        @Override/*from   ww w  .  ja  v  a 2s  . c  o  m*/
        public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
            if (Collections3.isNotEmpty(filters)) {

                List<Predicate> predicates = Lists.newArrayList();
                List<Predicate> ORpredicates = Lists.newArrayList();

                for (SearchFilter filter : filters) {
                    // nested path translate, Task??"user.name"filedName, ?Task.user.name
                    String[] names = StringUtils.split(filter.fieldName, ".");
                    Path expression = root.get(names[0]);
                    for (int i = 1; i < names.length; i++) {
                        expression = expression.get(names[i]);
                    }

                    Object value = filter.value;

                    if (expression.getJavaType().isEnum()) {
                        value = EnumUtils.valueOf(expression.getJavaType(), filter.value.toString());
                        predicates.add(builder.equal(expression, value));
                    } else {
                        // logic operator
                        switch (filter.operator) {
                        case EQ:
                            predicates.add(builder.equal(expression, filter.value));
                            break;
                        case LIKE:
                            predicates.add(builder.like(expression, "%" + filter.value + "%"));
                            break;
                        case GT:
                            predicates.add(builder.greaterThan(expression, (Comparable) filter.value));
                            break;
                        case LT:
                            predicates.add(builder.lessThan(expression, (Comparable) filter.value));
                            break;
                        case GTE:
                            predicates.add(builder.greaterThanOrEqualTo(expression, (Comparable) filter.value));
                            break;
                        case LTE:
                            predicates.add(builder.lessThanOrEqualTo(expression, (Comparable) filter.value));
                            break;
                        case NEQ:
                            predicates.add(builder.notEqual(expression, filter.value));
                            break;
                        case NOTNULL:
                            predicates.add(builder.isNotNull(expression));
                            break;
                        case ISNULL:
                            predicates.add(builder.isNull(expression));
                            break;
                        case OREQ:
                            ORpredicates.add(builder.equal(expression, filter.value));
                            break;
                        case ORLIKE:
                            ORpredicates.add(builder.like(expression, "%" + filter.value + "%"));
                            break;
                        case ORGT:
                            ORpredicates.add(builder.greaterThan(expression, (Comparable) filter.value));
                            break;
                        case ORLT:
                            ORpredicates.add(builder.lessThan(expression, (Comparable) filter.value));
                            break;
                        case ORGTE:
                            ORpredicates
                                    .add(builder.greaterThanOrEqualTo(expression, (Comparable) filter.value));
                            break;
                        case ORLTE:
                            ORpredicates.add(builder.lessThanOrEqualTo(expression, (Comparable) filter.value));
                            break;
                        case ORNEQ:
                            ORpredicates.add(builder.notEqual(expression, filter.value));
                            break;
                        case ORNOTNULL:
                            ORpredicates.add(builder.isNotNull(expression));
                            break;
                        case ORISNULL:
                            ORpredicates.add(builder.isNull(expression));
                            break;
                        }
                    }

                }

                // ? and ???
                if (!predicates.isEmpty() && !ORpredicates.isEmpty()) {
                    return builder.and(builder.and(predicates.toArray(new Predicate[predicates.size()])),
                            builder.or(ORpredicates.toArray(new Predicate[ORpredicates.size()])));
                }
                if (!predicates.isEmpty()) {
                    return builder.and(predicates.toArray(new Predicate[predicates.size()]));
                }
                if (!ORpredicates.isEmpty()) {
                    return builder.or(ORpredicates.toArray(new Predicate[ORpredicates.size()]));
                }
            }
            return builder.conjunction();
        }
    };
}

From source file:ca.uhn.fhir.jpa.dao.SearchBuilder.java

private Predicate createPredicateDateFromRange(CriteriaBuilder theBuilder,
        From<ResourceIndexedSearchParamDate, ResourceIndexedSearchParamDate> theFrom, DateRangeParam theRange) {
    Date lowerBound = theRange.getLowerBoundAsInstant();
    Date upperBound = theRange.getUpperBoundAsInstant();

    Predicate lb = null;//from  ww w. j  a v  a 2 s .co m
    if (lowerBound != null) {
        Predicate gt = theBuilder.greaterThanOrEqualTo(theFrom.<Date>get("myValueLow"), lowerBound);
        Predicate lt = theBuilder.greaterThanOrEqualTo(theFrom.<Date>get("myValueHigh"), lowerBound);
        if (theRange.getLowerBound().getPrefix() == ParamPrefixEnum.STARTS_AFTER
                || theRange.getLowerBound().getPrefix() == ParamPrefixEnum.EQUAL) {
            lb = gt;
        } else {
            lb = theBuilder.or(gt, lt);
        }
    }

    Predicate ub = null;
    if (upperBound != null) {
        Predicate gt = theBuilder.lessThanOrEqualTo(theFrom.<Date>get("myValueLow"), upperBound);
        Predicate lt = theBuilder.lessThanOrEqualTo(theFrom.<Date>get("myValueHigh"), upperBound);
        if (theRange.getUpperBound().getPrefix() == ParamPrefixEnum.ENDS_BEFORE
                || theRange.getUpperBound().getPrefix() == ParamPrefixEnum.EQUAL) {
            ub = lt;
        } else {
            ub = theBuilder.or(gt, lt);
        }
    }

    if (lb != null && ub != null) {
        return (theBuilder.and(lb, ub));
    } else if (lb != null) {
        return (lb);
    } else {
        return (ub);
    }
}

From source file:ca.uhn.fhir.jpa.dao.SearchBuilder.java

private Predicate createPredicateString(IQueryParameterType theParameter, String theParamName,
        CriteriaBuilder theBuilder,
        From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> theFrom) {
    String rawSearchTerm;/*from w  w  w.  j a  va  2  s .co m*/
    if (theParameter instanceof TokenParam) {
        TokenParam id = (TokenParam) theParameter;
        if (!id.isText()) {
            throw new IllegalStateException("Trying to process a text search on a non-text token parameter");
        }
        rawSearchTerm = id.getValue();
    } else if (theParameter instanceof StringParam) {
        StringParam id = (StringParam) theParameter;
        rawSearchTerm = id.getValue();
    } else if (theParameter instanceof IPrimitiveDatatype<?>) {
        IPrimitiveDatatype<?> id = (IPrimitiveDatatype<?>) theParameter;
        rawSearchTerm = id.getValueAsString();
    } else {
        throw new IllegalArgumentException("Invalid token type: " + theParameter.getClass());
    }

    if (rawSearchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
        throw new InvalidRequestException("Parameter[" + theParamName + "] has length ("
                + rawSearchTerm.length() + ") that is longer than maximum allowed ("
                + ResourceIndexedSearchParamString.MAX_LENGTH + "): " + rawSearchTerm);
    }

    String likeExpression = BaseHapiFhirDao.normalizeString(rawSearchTerm);
    likeExpression = createLeftMatchLikeExpression(likeExpression);

    Predicate singleCode = theBuilder.like(theFrom.get("myValueNormalized").as(String.class), likeExpression);
    if (theParameter instanceof StringParam && ((StringParam) theParameter).isExact()) {
        Predicate exactCode = theBuilder.equal(theFrom.get("myValueExact"), rawSearchTerm);
        singleCode = theBuilder.and(singleCode, exactCode);
    }
    return singleCode;
}

From source file:gov.osti.services.Metadata.java

/**
 * Acquire a List of records in pending ("Submitted") state, to be approved
 * for indexing and searching./* ww  w .  ja va  2 s  .co m*/
 *
 * JSON response is of the form:
 *
 * {"records":[{"code_id":n, ...} ],
 *  "start":0, "rows":20, "total":100}
 *
 * Where records is an array of DOECodeMetadata JSON, start is the beginning
 * row number, rows is the number requested (or total if less available),
 * and total is the total number of rows matching the filter.
 *
 * Return Codes:
 * 200 - OK, JSON is returned as above
 * 401 - Unauthorized, login is required
 * 403 - Forbidden, insufficient privileges (role required)
 * 500 - unexpected error
 *
 * @param start the starting row number (from 0)
 * @param rows number of rows desired (0 is unlimited)
 * @param siteCode (optional) a SITE OWNERSHIP CODE to filter by site
 * @param state the WORKFLOW STATE if desired (default Submitted and Announced). One of
 * Approved, Saved, Submitted, or Announced, if supplied.
 * @return JSON of a records response
 */
@GET
@Path("/projects/pending")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RequiresAuthentication
@RequiresRoles("OSTI")
public Response listProjectsPending(@QueryParam("start") int start, @QueryParam("rows") int rows,
        @QueryParam("site") String siteCode, @QueryParam("state") String state) {
    EntityManager em = DoeServletContextListener.createEntityManager();

    try {
        // get a JPA CriteriaBuilder instance
        CriteriaBuilder cb = em.getCriteriaBuilder();
        // create a CriteriaQuery for the COUNT
        CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
        Root<DOECodeMetadata> md = countQuery.from(DOECodeMetadata.class);
        countQuery.select(cb.count(md));

        Expression<String> workflowStatus = md.get("workflowStatus");
        Expression<String> siteOwnershipCode = md.get("siteOwnershipCode");

        // default requested STATE; take Submitted and Announced as the default values if not supplied
        List<DOECodeMetadata.Status> requestedStates = new ArrayList();
        String queryState = (StringUtils.isEmpty(state)) ? "" : state.toLowerCase();
        switch (queryState) {
        case "approved":
            requestedStates.add(DOECodeMetadata.Status.Approved);
            break;
        case "saved":
            requestedStates.add(DOECodeMetadata.Status.Saved);
            break;
        case "submitted":
            requestedStates.add(DOECodeMetadata.Status.Submitted);
            break;
        case "announced":
            requestedStates.add(DOECodeMetadata.Status.Announced);
            break;
        default:
            requestedStates.add(DOECodeMetadata.Status.Submitted);
            requestedStates.add(DOECodeMetadata.Status.Announced);
            break;
        }

        Predicate statusPredicate = workflowStatus.in(requestedStates);
        ParameterExpression<String> site = cb.parameter(String.class, "site");

        if (null == siteCode) {
            countQuery.where(statusPredicate);
        } else {
            countQuery.where(cb.and(statusPredicate, cb.equal(siteOwnershipCode, site)));
        }
        // query for the COUNT
        TypedQuery<Long> cq = em.createQuery(countQuery);
        cq.setParameter("status", requestedStates);
        if (null != siteCode)
            cq.setParameter("site", siteCode);

        long rowCount = cq.getSingleResult();
        // rows count should be less than 100 for pagination; 0 is a special case
        rows = (rows > 100) ? 100 : rows;

        // create a CriteriaQuery for the ROWS
        CriteriaQuery<DOECodeMetadata> rowQuery = cb.createQuery(DOECodeMetadata.class);
        rowQuery.select(md);

        if (null == siteCode) {
            rowQuery.where(statusPredicate);
        } else {
            rowQuery.where(cb.and(statusPredicate, cb.equal(siteOwnershipCode, site)));
        }

        TypedQuery<DOECodeMetadata> rq = em.createQuery(rowQuery);
        rq.setParameter("status", requestedStates);
        if (null != siteCode)
            rq.setParameter("site", siteCode);
        rq.setFirstResult(start);
        if (0 != rows)
            rq.setMaxResults(rows);

        RecordsList records = new RecordsList(rq.getResultList());
        records.setTotal(rowCount);
        records.setStart(start);

        return Response.ok().entity(mapper.valueToTree(records).toString()).build();
    } finally {
        em.close();
    }
}

From source file:ca.uhn.fhir.jpa.dao.SearchBuilder.java

private Predicate createPredicateQuantity(CriteriaBuilder theBuilder,
        From<ResourceIndexedSearchParamQuantity, ResourceIndexedSearchParamQuantity> theFrom,
        IQueryParameterType theParam) {/*from   w w w.jav a  2s.c  o  m*/
    String systemValue;
    String unitsValue;
    ParamPrefixEnum cmpValue;
    BigDecimal valueValue;
    String valueString;

    if (theParam instanceof BaseQuantityDt) {
        BaseQuantityDt param = (BaseQuantityDt) theParam;
        systemValue = param.getSystemElement().getValueAsString();
        unitsValue = param.getUnitsElement().getValueAsString();
        cmpValue = ParamPrefixEnum.forDstu1Value(param.getComparatorElement().getValueAsString());
        valueValue = param.getValueElement().getValue();
        valueString = param.getValueElement().getValueAsString();
    } else if (theParam instanceof QuantityParam) {
        QuantityParam param = (QuantityParam) theParam;
        systemValue = param.getSystem();
        unitsValue = param.getUnits();
        cmpValue = param.getPrefix();
        valueValue = param.getValue();
        valueString = param.getValueAsString();
    } else {
        throw new IllegalArgumentException("Invalid quantity type: " + theParam.getClass());
    }

    Predicate system = null;
    if (!isBlank(systemValue)) {
        system = theBuilder.equal(theFrom.get("mySystem"), systemValue);
    }

    Predicate code = null;
    if (!isBlank(unitsValue)) {
        code = theBuilder.equal(theFrom.get("myUnits"), unitsValue);
    }

    cmpValue = ObjectUtils.defaultIfNull(cmpValue, ParamPrefixEnum.EQUAL);
    final Expression<BigDecimal> path = theFrom.get("myValue");
    String invalidMessageName = "invalidQuantityPrefix";

    Predicate num = createPredicateNumeric(theBuilder, theParam, cmpValue, valueValue, path, invalidMessageName,
            valueString);

    Predicate singleCode;
    if (system == null && code == null) {
        singleCode = num;
    } else if (system == null) {
        singleCode = theBuilder.and(code, num);
    } else if (code == null) {
        singleCode = theBuilder.and(system, num);
    } else {
        singleCode = theBuilder.and(system, code, num);
    }

    return singleCode;
}

From source file:ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.java

private Set<Long> addPredicateQuantity(String theParamName, Set<Long> thePids,
        List<? extends IQueryParameterType> theList) {
    if (theList == null || theList.isEmpty()) {
        return thePids;
    }/*from  w w  w .j  a v  a 2  s.co  m*/

    CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
    CriteriaQuery<Long> cq = builder.createQuery(Long.class);
    Root<ResourceIndexedSearchParamQuantity> from = cq.from(ResourceIndexedSearchParamQuantity.class);
    cq.select(from.get("myResourcePid").as(Long.class));

    List<Predicate> codePredicates = new ArrayList<Predicate>();
    for (IQueryParameterType nextOr : theList) {
        IQueryParameterType params = nextOr;

        String systemValue;
        String unitsValue;
        QuantityCompararatorEnum cmpValue;
        BigDecimal valueValue;
        boolean approx = false;

        if (params instanceof BaseQuantityDt) {
            BaseQuantityDt param = (BaseQuantityDt) params;
            systemValue = param.getSystemElement().getValueAsString();
            unitsValue = param.getUnitsElement().getValueAsString();
            cmpValue = QuantityCompararatorEnum.VALUESET_BINDER
                    .fromCodeString(param.getComparatorElement().getValueAsString());
            valueValue = param.getValueElement().getValue();
        } else if (params instanceof QuantityParam) {
            QuantityParam param = (QuantityParam) params;
            systemValue = param.getSystem().getValueAsString();
            unitsValue = param.getUnits();
            cmpValue = param.getComparator();
            valueValue = param.getValue().getValue();
            approx = param.isApproximate();
        } else {
            throw new IllegalArgumentException("Invalid quantity type: " + params.getClass());
        }

        Predicate system = null;
        if (!isBlank(systemValue)) {
            system = builder.equal(from.get("mySystem"), systemValue);
        }

        Predicate code = null;
        if (!isBlank(unitsValue)) {
            code = builder.equal(from.get("myUnits"), unitsValue);
        }

        Predicate num;
        if (cmpValue == null) {
            BigDecimal mul = approx ? new BigDecimal(0.1) : new BigDecimal(0.01);
            BigDecimal low = valueValue.subtract(valueValue.multiply(mul));
            BigDecimal high = valueValue.add(valueValue.multiply(mul));
            Predicate lowPred = builder.gt(from.get("myValue").as(BigDecimal.class), low);
            Predicate highPred = builder.lt(from.get("myValue").as(BigDecimal.class), high);
            num = builder.and(lowPred, highPred);
        } else {
            switch (cmpValue) {
            case GREATERTHAN:
                Expression<Number> path = from.get("myValue");
                num = builder.gt(path, valueValue);
                break;
            case GREATERTHAN_OR_EQUALS:
                path = from.get("myValue");
                num = builder.ge(path, valueValue);
                break;
            case LESSTHAN:
                path = from.get("myValue");
                num = builder.lt(path, valueValue);
                break;
            case LESSTHAN_OR_EQUALS:
                path = from.get("myValue");
                num = builder.le(path, valueValue);
                break;
            default:
                throw new IllegalStateException(cmpValue.getCode());
            }
        }

        if (system == null && code == null) {
            codePredicates.add(num);
        } else if (system == null) {
            Predicate singleCode = builder.and(code, num);
            codePredicates.add(singleCode);
        } else if (code == null) {
            Predicate singleCode = builder.and(system, num);
            codePredicates.add(singleCode);
        } else {
            Predicate singleCode = builder.and(system, code, num);
            codePredicates.add(singleCode);
        }
    }

    Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));

    Predicate type = builder.equal(from.get("myResourceType"), myResourceName);
    Predicate name = builder.equal(from.get("myParamName"), theParamName);
    if (thePids.size() > 0) {
        Predicate inPids = (from.get("myResourcePid").in(thePids));
        cq.where(builder.and(type, name, masterCodePredicate, inPids));
    } else {
        cq.where(builder.and(type, name, masterCodePredicate));
    }

    TypedQuery<Long> q = myEntityManager.createQuery(cq);
    return new HashSet<Long>(q.getResultList());
}