Home > Enterprise >  Replacing Hibernate's Criteria API by JPA Criteria API
Replacing Hibernate's Criteria API by JPA Criteria API

Time:09-08

I have some legacy code written with an old Hibernate 3 version which I'd like to upgrade to 5.3. I am currently working on transitioning from Hibernate Criteria to JPA CriteriaBuilder.

I have something like this:

public List<ENTITY> findByCriteria(final Map<String, Object> criteriaMap, final List<String> fields, final Class<ENTITY> entityClass) {

        Session session = this.sessionFactory.getSessionFactory().getCurrentSession();

        final Criteria criteria =  session.createCriteria(entityClass);
        final Set<String> keys = criteriaMap.keySet();
        
        Object object;
        CriteriaValue criteriaValue;
        CriteriaValue.Operator operator;
        
    for (String key:keys) {
        object = criteriaMap.get(key);
        
        if (object instanceof SimpleExpression) {
            criteria.add((SimpleExpression)object);
        } else if (object instanceof LogicalExpression) {
            criteria.add((LogicalExpression)object);
        } else if (object instanceof Criterion) {
            criteria.add((Criterion)object);
        } else if (!isDefaultCriteria(key)) {
            if (!(object instanceof CriteriaValue)) {
                if (object instanceof String && ((String)object).contains(SYSTEMWILDCARD)) {
                    criteriaMap.put(key, new CriteriaValue(object, CriteriaValue.Operator.iLIKE));
                } else {
                    criteriaMap.put(key, new CriteriaValue(object, CriteriaValue.Operator.EQ));
                }
                
                object = criteriaMap.get(key);
            }
        
            operator = ((CriteriaValue)object).getOperator();
            criteriaValue = (CriteriaValue)object;
            
            if (criteriaValue != null) {
                Object value = criteriaValue.getValue();
                switch (operator) {
                    case EQ:
                        criteria.add(value == null ? Restrictions.isNull(key) : Restrictions.eq(key, value));
                        break;
                    case iLIKE:
                        criteria.add(Restrictions.ilike(key, cleanWildcards(value)));
                        break;
                    case LIKE:
                        criteria.add(Restrictions.like(key, cleanWildcards(value)));
                        break;
                    case LE:
                        criteria.add(Restrictions.le(key, value));
                        break;
                    case GE:
                        criteria.add(Restrictions.ge(key, value));
                        break;
                    case LT:
                        criteria.add(Restrictions.lt(key, value));
                        break;
                    case GT:
                        criteria.add(Restrictions.gt(key, value));
                        break;
                    case OR:
                        criteria.add(getOrRestrictions(key, value));
                        break;
                    case AND:
                        criteria.add(getAndRestrictions(key, value));
                        break;
                    case IN:
                        criteria.add(Restrictions.in(key, (Object[])value));
                        break;
                    case NE:
                        criteria.add(value == null ? Restrictions.isNotNull(key): Restrictions.ne(key, value));
                        break;
                }
            }
        } 
    }
    ....
}

Which I would rewrite like that:

CriteriaBuilder cb = sessionFactory.getCriteriaBuilder();
CriteriaQuery<?> cq = null;
try {
    cq = cb.createQuery(Class.forName(entityClass.getName()));
    cq.from(Class.forName(entityClass.getName()));
} catch (ClassNotFoundException e) {
    throw new RuntimeException(e);
}

List<?> books = sessionFactory.getCurrentSession().createQuery(cq).getResultList();

But my problem comes with the part where the Expressions and Restrictions are added to the criteria, as a corresponding .add() method is not available. How do I rewrite this segment?

CodePudding user response:

You build a list of javax.persistence.criteria.Predicate and in the end use cb.and( predicateList ) to build a final predicate which you can add to the query by passing it to cq.where()

  • Related