我在Java应用程序中使用Hibernate 5.1.0
。我将Postgres 9.5
与Postgis
个扩展程序和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。
一个明显的解决方案是删除其中一个功能。除此之外,有什么方法可以解决这个问题吗?
答案 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 = TRUE
是TRUE
)。只需删除它。
尝试编写一个看起来更像的函数:
SELECT b
FROM Block b
WHERE ST_Dwithin(b.geom, CAST(:geometry AS geometry), :distance);
(使用两个参数:geometry
和:distance
)