【问题标题】:Hibernate and Postgres : function st_buffer(bytea, numeric) is not uniqueHibernate 和 Postgres:函数 st_buffer(bytea, numeric) 不是唯一的
【发布时间】:2016-09-29 02:48:52
【问题描述】:

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

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。

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

【问题讨论】:

    标签: java postgresql postgis hibernate-5.x


    【解决方案1】:

    我不会声称对 Hibernate 了解很多,但似乎一个简单的解决方法是将 explicitly castCAST(:geometry AS geometry) 的 bytea,并现代化其余查询以添加“ST_”前缀,该前缀与较新的 PostGIS 版本。

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

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

    使用缓冲区选择区域比使用基于距离的ST_DWithin function 查找距离内的几何图形更慢且不完善。 ST_DWithin 也可以使用空间索引(如果可用)。布尔运算符不需要有= + UtilsHelper.getTrueBooleanValue(em) 部分(即TRUE = TRUETRUE)。只需将其删除。

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

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

    (使用两个参数:geometry:distance

    【讨论】:

    • 感谢您的回答,Mike T。我正在努力使它与 CAST 一起工作。无论如何,这可能只对 Postgres 有好处,而对 Oracle 没有好处。正如所评论的,我需要这个才能与两个数据库一起使用。这正是我依赖 Hibernate 生成实际查询的原因,无论是使用 ST_Buffer 还是 Postgres 的任何 ST_ 前缀或 Oracle 中的 SDO 等价物。
    • @krause 我不熟悉 Hibernate,但是 Oracle 有 SDO_WITHIN_DISTANCE 相当于上面提到的 ST_DWithin。
    猜你喜欢
    • 1970-01-01
    • 2023-01-08
    • 2013-07-14
    • 2016-02-28
    • 1970-01-01
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多