在JpaRepository的查询

时间:2016-11-08 13:14:59

标签: java postgresql spring-data-jpa postgis

我有一个像这样的JpaRepository:

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

第一个工作正常,但第二个在初始化期间抛出此异常:

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}

st_intersects有效且st_extent无法解释的原因

更新:我认为问题在于Spring Data JPA没有识别PostGIS功能。这个聚合函数(SQL&#39;和)可以正常工作:

@Query("select sum(p.id) from Pipe p where p.id in ?1")
Number getPipesSum(Collection<Number> ids);

2 个答案:

答案 0 :(得分:1)

我遇到了类似的问题,并按以下步骤解决了该问题:

在Spring Boot Repository界面中,可以使用st_astext()以WKT形式接收查询结果。

@Query(value = "SELECT st_astext(st_extent(p.geometry)) FROM Pipe p WHERE p.id IN ?1")
String getPipe(Collection<Number> id);

您将看到返回类型是String(可能不错,也可能不好)。

一旦从数据库取回WKT,我就使用org.locationtech.jts.geom.GeometryFactory将其转换回Geometry

@Autowired
private GeometryFactory factory;

WKTReader reader = new WKTReader(factory);
Geometry geom = reader.read(yourReturnVariable);

如果您查看geom.getGeometryType(),您会发现它是可行的几何图形,可将其用于其他操作。

就像我之前说的那样,这可能不是一个好的解决方案,但确实可行

答案 1 :(得分:0)

也许,因为st_extent函数返回box2d dataType。

查询的结果是

&#34; BOX(x1 y1,x2 y2)&#34; ,但您可以转换为几何

SELECT st_extent(p.geometry)::geometry FROM Pipe p WHERE p.id = ?1

或许(为了避免使用::)

SELECT st_geometryFromText(st_astext(st_extent(p.geometry))),<your SRID>) FROM Pipe p WHERE p.id = ?1

我希望它有效