Reputation: 4065
I have a JpaRepository like this one:
public interface PipeRepository extends JpaRepository<Pipe, Long> {
@Query("select p from Pipe p where st_intersects(p.geometry, ?1)=true")
Collection<Pipe> find(Geometry envelope);
@Query(value = "SELECT st_extent(p.geometry) FROM Pipe p WHERE p.id IN ?1")
Geometry getPipe(Collection<Number> id);
}
The first one works OK but the second one throws this exception during initialization:
org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: '('
+-[METHOD_NAME] IdentNode: 'st_extent' {originalText=st_extent}
\-[EXPR_LIST] SqlNode: 'exprList'
\-[DOT] DotNode: 'pipe0_.geometry' {propertyName=geometry,dereferenceType=PRIMITIVE,getPropertyPath=geometry,path=p.geometry,tableAlias=pipe0_,className=es.x.model.Pipe,classAlias=p}
+-[ALIAS_REF] IdentNode: 'pipe0_.id' {alias=p, className=es.x.model.Pipe, tableAlias=pipe0_}
\-[IDENT] IdentNode: 'geometry' {originalText=geometry}
Any hint of the reason why st_intersects
works and st_extent
doesn't?
UPDATE: I think that the issue is with Spring Data JPA not recognizing the PostGIS functions. This aggregate function (SQL's sum) works correctly:
@Query("select sum(p.id) from Pipe p where p.id in ?1")
Number getPipesSum(Collection<Number> ids);
Upvotes: 3
Views: 2830
Reputation: 506
I had a similar issue, and solved it as follows:
In your Spring Boot Repository interface, you can use st_astext() to receive your query results as WKT.
@Query(value = "SELECT st_astext(st_extent(p.geometry)) FROM Pipe p WHERE p.id IN ?1")
String getPipe(Collection<Number> id);
You will see that the return type is a String (which may or may not be good).
Once you have your WKT back from the database, I used org.locationtech.jts.geom.GeometryFactory to convert it back into a Geometry
@Autowired
private GeometryFactory factory;
WKTReader reader = new WKTReader(factory);
Geometry geom = reader.read(yourReturnVariable);
If you look at geom.getGeometryType()
you will see that it is a viable Geometry that you can then use in other operations.
As I said before, this may not be a good solution, but it does work
Upvotes: 2
Reputation: 498
Maybe, because the st_extent funtion returns box2d
dataType.
The result for the query is
"BOX(x1 y1,x2 y2)" , but you can cast to geometry
SELECT st_extent(p.geometry)::geometry FROM Pipe p WHERE p.id = ?1
Or perhaps (to avoid the use of ::)
SELECT st_geometryFromText(st_astext(st_extent(p.geometry))),<your SRID>) FROM Pipe p WHERE p.id = ?1
I hope it works
Upvotes: 1