Here is the Explanation of Equivalent JPA Criteria Query of
select * from mytable where until > from + interval 4 week;
First you have to create unit expression and extend it from BasicFunctionExpression for which take "WEEK" parameter as a unit and override its rendor(RenderingContext renderingContext) method only.
import java.io.Serializable;
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
import org.hibernate.query.criteria.internal.compile.RenderingContext;
import org.hibernate.query.criteria.internal.expression.function.BasicFunctionExpression;
public class UnitExpression extends BasicFunctionExpression<String> implements Serializable {
public UnitExpression(CriteriaBuilderImpl criteriaBuilder, Class<String> javaType,
String functionName) {
super(criteriaBuilder, javaType, functionName);
}
@Override
public String render(RenderingContext renderingContext) {
return getFunctionName();
}
}
then you use this unit expression in your JPA criteria Query.
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<MyTable> cq = cb.createQuery(MyTable.class);
Root<MyTable> root = cq.from(MyTable.class);
Expression<String> week= new UnitExpression(null, String.class, "WEEK");
Expression<Integer> timeDiff = cb.function(
"TIMESTAMPDIFF",
Integer.class,
week,
root.<Timestamp>get(MyTable_.until),
root.<Timestamp>get(MyTable_.from));
List<Predicate> conditions = new ArrayList<>();
conditions.add(cb.greaterThan(timeDiff, 4));
cq.where(conditions.toArray(new Predicate[]{}));
return session.createQuery(cq);
It is working fine.
CriteriaBuilder#function()
docs.oracle.com/javaee/6/api/javax/persistence/criteria/… although this break compatibility with different dbs, or if you can alter the table structure, you can add a column with the date difference. – Haim