Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Given the query example here: http://www.hibernatespatial.org/tutorial-hs4.html

Query query = em.createQuery("select e from Event e where within(e.location, :filter) = true", Event.class);
query.setParameter("filter", filter);

Is it possible to rewrite the query using jpa 2 criteria api?( I am unsure how i should deal with the within(e.location, :filter) part.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
474 views
Welcome To Ask or Share your Answers For Others

1 Answer

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...