First Issue: I have an existing code written for hibernate spatial 5 to find records within given radius, which works fine. I am in the process of migrating the code hibernate-spatial 6.1.7.Final. But getting below error:
java.lang.IllegalArgumentException: Passed `invariantType` for function return cannot be null
at org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers.invariant(StandardFunctionReturnTypeResolvers.java:45) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.function(SqmCriteriaNodeBuilder.java:1495) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.function(SqmCriteriaNodeBuilder.java:153) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
at com.adani.amm.specification.AssetLocationSpecification.toPredicate(AssetLocationSpecification.java:35) ~[classes/:na]
As per my debugging so far, it seems that POSTGIS geography function is not supported in the version. Below is a snippet of my code.
public class AssetLocationSpecification implements Specification<Location> {
/**
*
*/
private static final long serialVersionUID = 1L;
private final Double radius;
private final Double latitude;
private final Double longitude;
public AssetLocationSpecification(Double radius, Double latitude, Double longitude) {
super();
this.radius = radius;
this.latitude = latitude;
this.longitude = longitude;
}
@Override
public Predicate toPredicate(Root<Location> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
Expression<Geometry> geography = criteriaBuilder.function("geography", Geometry.class, root.get("geometry"));
Expression<Point> point = criteriaBuilder.function("ST_Point", Point.class, criteriaBuilder.literal(longitude),
criteriaBuilder.literal(latitude));
Expression<Point> centerPoint = criteriaBuilder.function("ST_SetSRID", Point.class, point,
criteriaBuilder.literal(4326));
Expression<Boolean> expression = criteriaBuilder.function(SpatialFunction.dwithin.toString(), boolean.class,
geography, centerPoint, criteriaBuilder.literal(radius));
return criteriaBuilder.equal(expression, true);
}
}
Second Issue: org.hibernate.spatial.SpatialFunction.dwithin is deprecated and replacement enum (org.hibernate.spatial.CommonSpatialFunction) does not contain that function.
I got the same error in a project of mine while performing exactly the same migration. I debugged the Hibernate Spatial code which produced the error, and as far as I understand the way the Hibernate types are registered changed in this version of Hibernate Spatial, and the
Geometrytype you use as return type in the first statement can't be found in the list of registered basic types. I can't be more specific because I also did not understand the mechanism completely.After saying that, this error looked to me too weird and made me considering if the mistake was not on my side. I thought maybe I was using the Spatial APi in an "uncommon" way, and I tried to refactor my code trying to be more generic, without using PostGIS functions directly.
My original code was this:
And I refactored to this:
You can see I do not use PostGIS anymore to create
Geometryobjects, but a GeometryFactory which I created this way:new GeometryFactory(new PrecisionModel(), 4326);This approach is database agnostic.
Applying the same approach to your case, you could try to write something like this: