I recently work at the exact same problem. My solution is a own Predicate for the within-keyword.
public class WithinPredicate extends AbstractSimplePredicate implements Serializable {
private final Expression<Point> matchExpression;
private final Expression<Geometry> area;
public WithinPredicate(CriteriaBuilderImpl criteriaBuilder, Expression<Point> matchExpression, Geometry area) {
this(criteriaBuilder, matchExpression, new LiteralExpression<Geometry>(criteriaBuilder, area));
}
public WithinPredicate(CriteriaBuilderImpl criteriaBuilder, Expression<Point> matchExpression, Expression<Geometry> area) {
super(criteriaBuilder);
this.matchExpression = matchExpression;
this.area = area;
}
public Expression<Point> getMatchExpression() {
return matchExpression;
}
public Expression<Geometry> getArea() {
return area;
}
public void registerParameters(ParameterRegistry registry) {
// Nothing to register
}
@Override
public String render(boolean isNegated, RenderingContext renderingContext) {
StringBuilder buffer = new StringBuilder();
buffer.append(" within(")
.append(((Renderable) getMatchExpression()).render(renderingContext))
.append(", ")
.append(((Renderable) getArea()).render(renderingContext))
.append(") = true ");
return buffer.toString();
}
}
Your query would look like this:
public List<Event> findEventInArea(Geometry area){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Event> c = cb.createQuery(Event.class);
Root<Event> event = c.from(Event.class);
c.where(new WithinPredicate((CriteriaBuilderImpl) cb, event.get(Event_.location), area));
Query query = entityManager.createQuery(c);
return query.getResultList();
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…