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()