1

I have a predicate(javax.persistence.criteria.Predicate) which filters raw data as follows:

    public Predicate byAccountsId(Collection<Long> accountsId) {
        ParameterExpression<?> param = createParam(AOraArrayUserType.class, new AOraArrayUserType(accountsId));
        return criteriaBuilder().or(
                criteriaBuilder()
                        .equal(criteriaBuilder().function("in_ex", Long.class, actSourceJoin().get(Account_.id),
                                param), 1),
                criteriaBuilder().equal(
                        criteriaBuilder().function("in_ex", Long.class, actDestinationJoin().get(Account_.id),
                                param), 1));
    }

This predicate builds the next part of the query:

..
where
..
act.source_id in (accountsId.values())
or act.destination_id in (accountsId.values() - array ids)
..

It works fine but there may be too much raw data.I want to use "Oracle functional index", which removes unnecessary data from the query results. I tried to rewrite my predicate as follows:

    public Predicate byAccountsId(Collection<Long> accountsId) {
        ParameterExpression<?> param = createParam(AOraArrayUserType.class, new AOraArrayUserType(accountsId));
        return criteriaBuilder().or(
                criteriaBuilder().literal(
                        Restrictions.sqlRestriction("case when state != 'ARCHIVE' then source_id else null end"))
                        .in(param));
    }

Resurlt query builds fine but returns no result. But when I copy result query to sql developer and run the query it returns the expected result.

Part of the query which is build by new predicate:

..
where 
..
(case when act.state != 'ARCHIVE' then act.source_id else null end) in (accountsId.values() - array ids)
..

Does anybody know why I don't get the correct result when I'm using the new predicate? And can I use hibernate.criterion.Restrictions with javax.persistence.criteria.Predicate?

0

1 Answer 1

1

You can define @Formula for the expression in your Entity (AOraArrayUserType) and use the field in criteria

Restrictions.in("theFormulaField", param)
Sign up to request clarification or add additional context in comments.

1 Comment

thank. Result code follows: @Formula("CASE WHEN state = 'ARCHIVE' THEN 1 ELSE 0 END") private boolean archived; and using this formula: criteriaBuilder().equal(root().get(Act_.archived), false);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.