Hibernate和Postgres:函数st_buffer(bytea,numeric)不是唯一的

时间:2016-05-31 07:45:05

标签: java postgresql postgis hibernate-5.x

我在Java应用程序中使用Hibernate 5.1.0。我将Postgres 9.5Postgis个扩展程序和Oracle数据库连接起来。 我需要找到数据库中与我应用缓冲区的给定几何体相交的所有几何,例如:

Query query = session
            .createQuery("select b from Block b where intersects(b.geom, buffer(:geometry, " + bufferDistance + ")) = "
                    + UtilsHelper.getTrueBooleanValue(em));
query.setParameter("geometry", geom);
List<Block> blocks = query.list();

这适用于Oracle,但在Postgres中我会收到错误:

Caused by: org.postgresql.util.PSQLException: ERROR: function st_buffer(bytea, numeric) is not unique
Hint: Could not choose a best candidate function. You might need to add explicit type casts.
Position: 243
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270)

这是有道理的,因为它无法在以下功能之一中进行选择:

geometry ST_Buffer(geometry g1, float radius_of_buffer);
geography ST_Buffer(geography g1, float radius_of_buffer_in_meters);

UtilsHelper.getTrueBooleanValue(em)将获得正确的布尔值,具体取决于实体管理器,即Oracle为0/1,Postgres为true / false。

一个明显的解决方案是删除其中一个功能。除此之外,有什么方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

我不会声称对Hibernate有很多了解,但似乎只需要explicitly cast ST_DWithin function带有CAST(:geometry AS geometry)的bytea,并对其余查询进行现代化以添加&#34 ; ST _&#34;前缀,用于较新的PostGIS版本。

更重要的是,您永远不应该使用以下格式编写查询:

SELECT b
FROM Block b
WHERE ST_Intersects(b.geom, ST_Buffer(CAST(:geometry AS geometry), :bufferDistance)) = TRUE;

使用缓冲区选择区域比使用基于距离的http://apidock.com/rails/ActiveRecord/FinderMethods/second来查找距离内的几何图形更慢且不完美。如果可用,ST_DWithin也可以使用空间索引。布尔运算符不需要= + UtilsHelper.getTrueBooleanValue(em)部分(即TRUE = TRUETRUE)。只需删除它。

尝试编写一个看起来更像的函数:

SELECT b
FROM Block b
WHERE ST_Dwithin(b.geom, CAST(:geometry AS geometry), :distance);

(使用两个参数:geometry:distance