【问题标题】:Hibernate spatial query exception, but in the postgres console is workingHibernate 空间查询异常,但在 postgres 控制台中工作
【发布时间】:2016-10-02 11:34:29
【问题描述】:

我正在尝试使用 Hibernate 和 Hibernate Spatial 在我的 Java 代码中执行此查询:

Query q = s.createQuery("SELECT c FROM crimes c WHERE ST_DWITHIN(ST_MakeLine(ARRAY['SRID=4326;POINT(-49.30621000000001 -25.515020000000003)','SRID=4326;POINT(-49.30619 -25.515770000000003)','SRID=4326;POINT(-49.306180000000005 -25.5162)','SRID=4326;POINT(-49.305780000000006 -25.5162)']), c.location, 0.0001) = true;");

但是,这个查询会导致异常:

e = (org.hibernate.hql.internal.ast.QuerySyntaxException) org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE_BRACKET, found ',' near line 1, column 151 [SELECT c FROM com.safecity.server.db.model.EntityCrime c WHERE ST_DWITHIN(ST_MakeLine(ARRAY['SRID=4326;POINT(-49.305820000000004 -25.515330000000002)','SRID=4326;POINT(-49.306200000000004 -25.515340000000002)','SRID=4326;POINT(-49.30619 -25.515770000000003)','SRID=4326;POINT(-49.306180000000005 -25.5162)','SRID=4326;POINT(-49.305780000000006 -25.5162)']), c.location, 0.0001) = true]

我检查了查询,但找不到错误。但是,如果我得到同样的查询并在 postgres 控制台上执行,则查询执行时不会出现任何错误并返回正确的值。

拜托,有人可以帮助我吗? 谢谢。

【问题讨论】:

  • 在此过程中,简化您的查询。 ST_DWITHIN() 已经返回 boolean。无需附加= true,这只是噪音:SELECT c FROM crimes c WHERE ST_DWITHIN(ST_MakeLine(ARRAY[ ... ]), c.location, 0.0001)
  • 谢谢,我会改的

标签: java postgresql hibernate hibernate-spatial


【解决方案1】:

您在 hibernate 中使用本机查询。为此,您必须使用如下查询:

Query q = s.createSQLQuery("SELECT c FROM crimes c WHERE ST_DWITHIN(ST_MakeLine(ARRAY['SRID=4326;POINT(-49.30621000000001 -25.515020000000003)','SRID=4326;POINT(-49.30619 -25.515770000000003)','SRID=4326;POINT(-49.306180000000005 -25.5162)','SRID=4326;POINT(-49.305780000000006 -25.5162)']), c.location, 0.0001) = true;");

如果您想创建数据库原生查询而不是 HQL,请使用 createSQLQuery() 而不是 createQuery()。

【讨论】:

  • 我尝试了您的建议,但现在正在发生其他异常:e = (org.hibernate.MappingException) org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111. 你知道为什么吗?
  • 它是一个类型映射异常,表示列类型不能通过hibernate映射到数据库类型。如果您无法正确映射事物,请添加您的整个代码(pojo 类、表结构和触发查询的主类。)
  • 这很奇怪,因为我使用另一个查询,具有相同的表和对象,并且它没有抛出任何异常。但是,我在另一个查询中只使用了 createQuery,而不是 createSQLQuery。
  • 请记住,使用本机查询您不会检索对象。相反,您将直接获取列值(与 jdbc 简单语句相同)而不是对象。使用 createSQLQuery 它返回一个对象,即 HQL 查询。如果要使用 HQL,则需要修改 HQL 格式的查询并使用 createQuery 语句。
  • 上述评论中有一个小错字; createQuery 它返回一个对象
【解决方案2】:

我解决了这个改变查询的问题,对于这个:

Query q = s.createQuery("SELECT c FROM crimes c WHERE ST_DWITHIN(ST_GeomFromText('LINESTRING(-49.305820000000004 -25.515330000000002,-49.306200000000004 -25.515340000000002,-49.30619 -25.515770000000003,-49.306180000000005 -25.5162,-49.305780000000006 -25.5162)', 4326), c.location, 0.0001) = true");

我不知道为什么,但它有效。

感谢您的帮助。

【讨论】:

    【解决方案3】:

    我之前在 Hibernate 中看到过与 ARRAY constructors 类似的问题。

    替换为数组文字(以及可选的类型转换)以使其工作。一个简单的string literal 将避免沟通中的各种复杂情况。

    您正在使用PostGis function ST_MakeLine() 将geometry 的数组作为输入参数。

    几何ST_MakeLine(geometry[] geoms_array)

    所以:

    Query q = s.createQuery(
      "SELECT c FROM crimes c
       WHERE  ST_DWITHIN(ST_MakeLine('{SRID=4326;POINT(-49.30621000000001 -25.515020000000003)
                                      ,SRID=4326;POINT(-49.30619 -25.515770000000003)
                                      ,SRID=4326;POINT(-49.306180000000005 -25.5162)
                                      ,SRID=4326;POINT(-49.305780000000006 -25.5162)}'::geometry[]), c.location, 0.0001)");
    

    这也可以解释为什么 your alternative answer 提供一个线串(作为字符串字面量!)同样有效。

    还简化了WHERE 子句like I commented 中的布尔表达式。附加= true 只是噪音。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 2010-11-17
      • 2022-01-02
      相关资源
      最近更新 更多