休眠空间:找不到函数

hibernate-spatial: can't find function

我在使用 H2 和 GeoDB(内存中,junit)时遇到问题。

此外,使用 Hibernate 5(每个包的最新版本,包括 hibernate-spatial)和 Spring 4.

通过 id 实体进行持久化和查询工作得很好。可以毫无问题地识别几何类型。

当我尝试使用地理空间函数查询数据库时出现问题,Hibernate 失败说他找不到该函数:

[ERROR] 2015-12-16 11:16:15,000: org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions:129: Function "ST_CONTAINS" not found; SQL statement:
select geoentity0_.id as id1_0_, geoentity0_.location as location2_0_, geoentity0_.name as name3_0_ from GEO_ENTITY geoentity0_ where ST_Contains(geoentity0_.location, ?)=1 [90022-190]

看起来我正在使用 dialect.Here 的探针(在 persistence.xml 中):

<property name="hibernate.dialect" value="org.hibernate.spatial.dialect.h2geodb.GeoDBDialect" />

这些是我正在使用的部门:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.190</version>
    <scope>test</scope>
</dependency>
<dependency>
          <groupId>org.opengeo</groupId>
          <artifactId>geodb</artifactId>
          <version>0.7</version>
          <scope>test</scope>  
</dependency>

我做错了什么,我该如何解决?

编辑:添加h2gis

我已经尝试将 h2gis 添加到我的部门,但没有更改错误。我也尝试用 h2gis 替换 geodb,结果相同。

<dependency>
    <groupId>org.orbisgis</groupId>
    <artifactId>h2spatial-ext</artifactId>
    <version>1.2.3</version>
</dependency>

找到解决方案并在此处发布以留下跟踪。

此解决方案适用于 h2 + geodb,但我想如果有一点耐心,也可以为 h2gis 找到类似的解决方案。

我缺少的是在名为 import.sql 的模式导出中执行的 SQL 文件,该文件位于类路径根目录中,它在 H2 层中创建了函数。

这个文件的内容是:

CREATE ALIAS AddGeometryColumn for "geodb.GeoDB.AddGeometryColumn"
CREATE ALIAS CreateSpatialIndex for "geodb.GeoDB.CreateSpatialIndex"
CREATE ALIAS DropGeometryColumn for "geodb.GeoDB.DropGeometryColumn"
CREATE ALIAS DropGeometryColumns for "geodb.GeoDB.DropGeometryColumns"
CREATE ALIAS DropSpatialIndex for "geodb.GeoDB.DropSpatialIndex"
CREATE ALIAS EnvelopeAsText for "geodb.GeoDB.EnvelopeAsText"
CREATE ALIAS GeometryType for "geodb.GeoDB.GeometryType"
CREATE ALIAS ST_Area FOR "geodb.GeoDB.ST_Area"
CREATE ALIAS ST_AsEWKB FOR "geodb.GeoDB.ST_AsEWKB"
CREATE ALIAS ST_AsEWKT FOR "geodb.GeoDB.ST_AsEWKT"
CREATE ALIAS ST_AsHexEWKB FOR "geodb.GeoDB.ST_AsHexEWKB"
CREATE ALIAS ST_AsText FOR "geodb.GeoDB.ST_AsText"
CREATE ALIAS ST_BBOX FOR "geodb.GeoDB.ST_BBox"
CREATE ALIAS ST_Buffer FOR "geodb.GeoDB.ST_Buffer"
CREATE ALIAS ST_Centroid FOR "geodb.GeoDB.ST_Centroid"
CREATE ALIAS ST_Crosses FOR "geodb.GeoDB.ST_Crosses"
CREATE ALIAS ST_Contains FOR "geodb.GeoDB.ST_Contains"
CREATE ALIAS ST_DWithin FOR "geodb.GeoDB.ST_DWithin"
CREATE ALIAS ST_Disjoint FOR "geodb.GeoDB.ST_Disjoint"
CREATE ALIAS ST_Distance FOR "geodb.GeoDB.ST_Distance"
CREATE ALIAS ST_Envelope FOR "geodb.GeoDB.ST_Envelope"
CREATE ALIAS ST_Equals FOR "geodb.GeoDB.ST_Equals"
CREATE ALIAS ST_GeoHash FOR "geodb.GeoDB.ST_GeoHash"
CREATE ALIAS ST_GeomFromEWKB FOR "geodb.GeoDB.ST_GeomFromEWKB"
CREATE ALIAS ST_GeomFromEWKT FOR "geodb.GeoDB.ST_GeomFromEWKT"
CREATE ALIAS ST_GeomFromText FOR "geodb.GeoDB.ST_GeomFromText"
CREATE ALIAS ST_GeomFromWKB FOR "geodb.GeoDB.ST_GeomFromWKB"
CREATE ALIAS ST_Intersects FOR "geodb.GeoDB.ST_Intersects"
CREATE ALIAS ST_IsEmpty FOR "geodb.GeoDB.ST_IsEmpty"
CREATE ALIAS ST_IsSimple FOR "geodb.GeoDB.ST_IsSimple"
CREATE ALIAS ST_IsValid FOR "geodb.GeoDB.ST_IsValid"
CREATE ALIAS ST_MakePoint FOR "geodb.GeoDB.ST_MakePoint"
CREATE ALIAS ST_MakeBox2D FOR "geodb.GeoDB.ST_MakeBox2D"
CREATE ALIAS ST_Overlaps FOR "geodb.GeoDB.ST_Overlaps"
CREATE ALIAS ST_SRID FOR "geodb.GeoDB.ST_SRID"
CREATE ALIAS ST_SetSRID FOR "geodb.GeoDB.ST_SetSRID"
CREATE ALIAS ST_Simplify FOR "geodb.GeoDB.ST_Simplify"
CREATE ALIAS ST_Touches FOR "geodb.GeoDB.ST_Touches"
CREATE ALIAS ST_Within FOR "geodb.GeoDB.ST_Within"
CREATE ALIAS Version FOR "geodb.GeoDB.Version"

在启动时添加 org.opengeo:geodbcom.h2database:h2 依赖项,然后 运行 GeoDB.InitGeoDB(dataSource.getConnection())

org.hibernate.spatial.dialect.h2geodb.GeoDBDialect 对于 hibernate.dialect 很好。

Gradle:

testCompile('com.h2database:h2:1.4.196')
testCompile('org.opengeo:geodb:0.8')

spring的示例(如果不想不必要地创建布尔 bean,可以美化代码):

@Bean
public boolean initGeoDB(final DataSource dataSource) throws SQLException {
    final Connection cx = dataSource.getConnection();
    GeoDB.InitGeoDB(cx);
    return true;
}