title: Predicates in Hibernate-Spatial + PostGIS to search within miles radius with Latitude / Longitude
body: <p>I am trying to use Predicates in Hibernate-Spatial to search within a radius of X miles (user defined).</p>
  
  <p>Though this sort of question has been asked before, only once before with Predicates and may not be current as it does not work. And I have to be able to use predicates and NOT HQL.</p>
  
  <p>I found via another answer how to setup a Predicate for the WITHIN keyword of PostGIS but have been unable to get the query to run.</p>
  
  <p>After setup at the end I state the error output and package versions.</p>
  
  <p>Here is what I have in my schema:</p>
  
  <pre><code>CREATE EXTENSION Postgis;
  
  CREATE TABLE "user" (
      id               bigint  NOT NULL,
      search_radius    int,
      latitude         double precision,
      longitude        double precision,
      location         geography(point, 4326),
  
      PRIMARY KEY (id)
  );
  </code></pre>
  
  <p>In my model:</p>
  
  <pre><code>import com.vividsolutions.jts.geom.Point;
  import com.vividsolutions.jts.io.ParseException;
  import com.vividsolutions.jts.io.WKTReader;
  import org.hibernate.annotations.Type;
  
  @Entity
  @Table(name = "`user`")
  public class User implements UserDetails {
      @Id
      private Long id;
      private Integer searchRadius = 125;
      private Double latitude;
      private Double longitude;
      @Column(name = "location", columnDefinition = "geography(Point, 4326)", nullable = true)
      @Type(type = "jts_geometry")
      private Point location;
  
      ...
  
      private void updateLocation() {
          if (latitude != null &amp;&amp; longitude != null) {
              try {
                  location = (Point) new WKTReader().read("POINT(" + latitude + " " + longitude + ")");
                  location.setSRID(Location.SRID);
              } catch (ParseException e) {
                  e.printStackTrace();
                  throw new RuntimeException(e);
              }
          }
      }
  }
  </code></pre>
  
  <p>Where update location is called inside setters of lat / lng.</p>
  
  <p>The predicate, which I obtained from <a href="https://stackoverflow.com/questions/18822133/using-jpa-criteria-api-and-hibernate-spatial-4-together">Using JPA Criteria Api and hibernate spatial 4 together</a></p>
  
  <pre><code>import com.vividsolutions.jts.geom.Geometry;
  import com.vividsolutions.jts.geom.Point;
  import java.io.Serializable;
  import javax.persistence.criteria.Expression;
  import org.hibernate.jpa.criteria.CriteriaBuilderImpl;
  import org.hibernate.jpa.criteria.ParameterRegistry;
  import org.hibernate.jpa.criteria.Renderable;
  import org.hibernate.jpa.criteria.compile.RenderingContext;
  import org.hibernate.jpa.criteria.predicate.AbstractSimplePredicate;
  
  public class WithinPredicate extends AbstractSimplePredicate implements Expression&lt;Boolean&gt;, Serializable {
      private final Expression&lt;Point&gt; matchExpression;
      private final Expression&lt;Geometry&gt; area;
  
      public WithinPredicate(CriteriaBuilderImpl criteriaBuilder, Expression&lt;Point&gt; matchExpression, Expression&lt;Geometry&gt; area) {
          super(criteriaBuilder);
          this.matchExpression = matchExpression;
          this.area = area;
      }
  
      public Expression&lt;Point&gt; getMatchExpression() {
          return matchExpression;
      }
  
      public Expression&lt;Geometry&gt; 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 ");
          String bo = buffer.toString();
  
          return bo;
      }
  }
  </code></pre>
  
  <p>And creating the query, using the WithinPredicate and circle factory.</p>
  
  <pre><code>import com.xxxx.repository.WithinPredicate;
  import com.vividsolutions.jts.geom.Coordinate;
  import com.vividsolutions.jts.geom.Geometry;
  import com.vividsolutions.jts.util.GeometricShapeFactory;
  
  @Service
  class ... {
      public List&lt;User&gt; fetchFor(User user) {
          ...
          Geometry radius = createCircle(user.getLatitude(), user.getLongitude(), user.getSearchRadius());
          radius.setSRID(Location.SRID);
          p = b.and(p, new WithinPredicate(
              (CriteriaBuilderImpl) b,
              u.get(User_.location),
              new LiteralExpression&lt;Geometry&gt;((CriteriaBuilderImpl) b, radius)
          ));
      }
  
      private static Geometry createCircle(double x, double y, final double RADIUS) {
          GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
          shapeFactory.setNumPoints(32);
          shapeFactory.setCentre(new Coordinate(x, y));//there are your coordinates
          shapeFactory.setSize(RADIUS * 2);//this is how you set the radius
          return shapeFactory.createCircle().getBoundary();
      }
  }
  </code></pre>
  
  <p>Unfortunately, the error I get on the output is:</p>
  
  <pre><code>2016-09-09 14:03:30.862  WARN 56393 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 42883
  2016-09-09 14:03:30.862 ERROR 56393 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: function st_within(geography, bytea) does not exist
    Hint: No function matches the given name and argument types. You might need to add explicit type casts.
    Position: 336
  </code></pre>
  
  <p>Hibernate-spatial version in gradle:</p>
  
  <pre><code>compile('org.hibernate:hibernate-spatial:5.0.9.Final')
  </code></pre>
  
  <p>I suspect the issue is due to perhaps the model / schema being set to a type of "Geography(Point, 4326)" but the shapeFactory creating a radius of type "Geometry(Point, 4326)".</p>
  
  <p>Really appreciate any help on this. Thanks.</p>