【问题标题】:Execute PostGIS functions in a JpaRepository's query在 JpaRepository 的查询中执行 PostGIS 函数
【发布时间】:2017-03-22 03:16:41
【问题描述】:

我有一个像这样的 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 的总和)工作正常:

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

【问题讨论】:

标签: java postgresql spring-data-jpa postgis


【解决方案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);

你会看到返回类型是一个字符串(可能好也可能不好)。

从数据库中获取 WKT 后,我使用 org.locationtech.jts.geom.GeometryFactory 将其转换回几何图形

@Autowired
private GeometryFactory factory;

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

如果您查看 geom.getGeometryType(),您会发现它是一个可行的 Geometry,然后您可以将其用于其他操作。

正如我之前所说,这可能不是一个好的解决方案,但它确实有效

【讨论】:

    【解决方案2】:

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

    查询的结果是

    "BOX(x1 y1,x2 y2)" ,但您可以转换为几何体

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

    或者也许(避免使用 ::)

    SELECT st_geometryFromText(st_astext(st_extent(p.geometry))),&lt;your SRID&gt;) FROM Pipe p WHERE p.id = ?1

    我希望它有效

    【讨论】:

    • 我需要st_extent,因为它是一个聚合函数。在我的实际用例中,查询是 WHERE p.id IN ?1 是一个 ID 列表的参数,我想要所有涉及的几何图形的范围。我编辑我的问题。
    • 我编辑第二个查询,用geomfromtext,你有几何,然后你可以解析
    • 同样的例外(其中还提到了两个 postgis 函数)。投射选项不起作用 (unexpected token: : near line 1, column 29)。
    • 看 [postgis.net/docs/manual-2.3/ST_Extent.html] ,它显示了如何强制回到几何体——强制回到几何体——并渲染该几何体的扩展文本表示 SELECT ST_SetSRID(ST_Extent(the_geom),2249 ) 作为 bextent FROM sometable;
    • 我认为问题在于 spring-data-jpa 无法识别 postgis 函数。我编辑我的问题。
    猜你喜欢
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 2019-10-05
    • 2015-01-08
    • 2014-10-11
    • 1970-01-01
    相关资源
    最近更新 更多