带有EntityManager.createQuery的Postgres / PostGIS st_distance_sphere函数无法理解的错误

时间:2019-11-25 14:35:56

标签: postgresql hibernate kotlin spring-data-jpa postgis

我尝试使用PostGIS计算两点之间的距离。我发现postGIS为此提供了st_distance_sphere function,并尝试了以下代码:

private fun getDeliveryDistance(areaCentroid: Point, buyerLocation: Point): Double {
    val query = em.createQuery(
        "select st_distance_sphere(st_makepoint(${areaCentroid.x}, ${areaCentroid.y}), st_makepoint(${buyerLocation.x}, ${buyerLocation.y}))",
        Double::class.java
    )
    val result = query.singleResult
    return result
}

但不是正确的结果,而是出现以下错误:

java.lang.IllegalArgumentException: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode 
 \-[METHOD_CALL] MethodNode: '('
    +-[METHOD_NAME] IdentNode: 'st_distance_sphere' {originalText=st_distance_sphere}
    \-[EXPR_LIST] SqlNode: 'exprList'
       +-[METHOD_CALL] MethodNode: '('
       |  +-[METHOD_NAME] IdentNode: 'st_makepoint' {originalText=st_makepoint}
       |  \-[EXPR_LIST] SqlNode: 'exprList'
       |     +-[NUM_DOUBLE] LiteralNode: '38.970335125923135'
       |     \-[NUM_DOUBLE] LiteralNode: '45.0543938370861'
       \-[METHOD_CALL] MethodNode: '('
          +-[METHOD_NAME] IdentNode: 'st_makepoint' {originalText=st_makepoint}
          \-[EXPR_LIST] SqlNode: 'exprList'
             +-[NUM_DOUBLE] LiteralNode: '38.97033512592316'
             \-[NUM_DOUBLE] LiteralNode: '45.05439383708615'
 [select st_distance_sphere(st_makepoint(38.970335125923135, 45.0543938370861), st_makepoint(38.97033512592316, 45.05439383708615))]]

不幸的是,我不知道这个错误。但是,当我在调用getSingleResult()之前以调试模式或从堆栈跟踪的最后一行复制查询,然后在pgAdmin控制台中执行该查询时,我得到了正确的结果。有人知道我该如何解决吗?

1 个答案:

答案 0 :(得分:0)

@Query(
    """select topology.st_distance(topology.st_makepoint(:restaurantLat, :restaurantLong), topology.st_makepoint(:buyerLat, :buyerLong))""",
    nativeQuery = true
)
fun calculateDistance(
    @Param("restaurantLat") restaurantLat: Double,
    @Param("restaurantLong") restaurantLong: Double,
    @Param("buyerLat") buyerLat: Double,
    @Param("buyerLong") buyerLong: Double
): Double

我只是明确指定了postgres模式,它解决了我的问题