Skip to content

Latest commit

 

History

History
250 lines (204 loc) · 13.6 KB

File metadata and controls

250 lines (204 loc) · 13.6 KB

Spatial

Overview

Hibernate Spatial was originally developed as a generic extension to Hibernate for handling geographic data. Since 5.0, Hibernate Spatial is now part of the Hibernate ORM project, and it allows you to deal with geographic data in a standardized way.

Hibernate Spatial provides a standardized, cross-database interface to geographic data storage and query functions. It supports most of the functions described by the OGC Simple Feature Specification. Supported databases are Oracle 19c/21c/23ai, PostgreSQL/PostGIS, MySQL, Microsoft SQL Server, DB2, CockroachDB and H2/GeoDB.

Spatial data types are not part of the Java standard library, and they are absent from the JDBC specification. Over the years JTS has emerged as the de facto standard to fill this gap. JTS is an implementation of the Simple Feature Specification (SFS). Many databases on the other hand implement the SQL/MM - Part 3: Spatial Data specification - a related, but broader specification. The biggest difference is that SFS is limited to 2D geometries in the projected plane (although JTS supports 3D coordinates), whereas SQL/MM supports 2-, 3- or 4-dimensional coordinate spaces.

Hibernate Spatial supports two different geometry models: JTS and geolatte-geom. As already mentioned, JTS is the de facto standard. Geolatte-geom (also written by the lead developer of Hibernate Spatial) is a more recent library that supports many features specified in SQL/MM but not available in JTS (such as support for 4D geometries, and support for extended WKT/WKB formats). Geolatte-geom also implements encoders/decoders for the database native types. Geolatte-geom has good interoperability with JTS. Converting a Geolatte geometry to a JTS geometry, for instance, doesn’t require copying of the coordinates. It also delegates spatial processing to JTS.

Whether you use JTS or Geolatte-geom, Hibernate spatial maps the database spatial types to your geometry model of choice. It will, however, always use Geolatte-geom to decode the database native types.

Hibernate Spatial also makes a number of spatial functions available in HQL and in the Criteria Query API. These functions are specified in both SQL/MM as SFS, and are commonly implemented in databases with spatial support (see Hibernate Spatial dialect function support)

Configuration

Hibernate Spatial requires some configuration prior to start using it.

Dependency

You need to include the hibernate-spatial dependency in your build environment. For Maven, you need to add the following dependency:

Example 1. Maven dependency
<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-spatial</artifactId>
    <version>${hibernate.version}</version>
</dependency>

Hibernate defines common spatial functions uniformly over all databases. These functions largely correspond to those specified in the Simple Feature Specification. Not all databases are capable of supporting every function, however. The table below details which functions are supported by various database systems.

Table 1. Hibernate Spatial dialect function support

Function

Description

PostgresSQL

Oracle 19c/21c/23ai

MySQL

SQLServer

H2GIS

DB2

CockroachDB

Basic functions on Geometry

int st_dimension(Geometry)

SFS §2.1.1.1

[check]

[check]

[check]

[check]

[check]

[check]

[check]

String st_geometrytype(Geometry)

SFS §2.1.1.1

[check]

[check]

[check]

[check]

[check]

[check]

[check]

int st_srid(Geometry)

SFS §2.1.1.1

[check]

[check]

[check]

[check]

[check]

[check]

[check]

Geometry st_envelope(Geometry)

SFS §2.1.1.1

[check]

[check]

[check]

[check]

[check]

[check]

[check]

String st_astext(Geometry)

SFS §2.1.1.1

[check]

[check]

[check]

[check]

[check]

[check]

[check]

byte[] st_asbinary(Geometry)

SFS §2.1.1.1

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_isempty(Geometry)

SFS §2.1.1.1

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_issimple(Geometry)

SFS §2.1.1.1

[check]

[check]

[check]

[check]

[check]

[check]

[check]

Geometry st_boundary(Geometry)

SFS §2.1.1.1

[check]

[check]

[times]

[check]

[check]

[check]

[check]

Functions for testing Spatial Relations between geometric objects

boolean st_equals(Geometry, Geometry)

SFS §2.1.1.2

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_disjoint(Geometry, Geometry)

SFS §2.1.1.2

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_intersects(Geometry, Geometry)

SFS §2.1.1.2

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_touches(Geometry, Geometry)

SFS §2.1.1.2

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_crosses(Geometry, Geometry)

SFS §2.1.1.2

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_within(Geometry, Geometry)

SFS §2.1.1.2

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_contains(Geometry, Geometry)

SFS §2.1.1.2

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_overlaps(Geometry, Geometry)

SFS §2.1.1.2

[check]

[check]

[check]

[check]

[check]

[check]

[check]

boolean st_relate(Geometry, Geometry, String)

SFS §2.1.1.2

[check]

[check]

[times]

[check]

[check]

[check]

[check]

Functions that support Spatial Analysis

double st_distance(Geometry, Geometry)

SFS §2.1.1.3

[check]

[check]

[check]

[check]

[check]

[check]

[check]

Geometry st_buffer(Geometry, double)

SFS §2.1.1.3

[check]

[check]

[check]

[check]

[check]

[check]

[check]

Geometry st_convexhull(Geometry)

SFS §2.1.1.3

[check]

[check]

[check]

[check]

[check]

[check](1)

[times]

Geometry st_intersection(Geometry, Geometry)

SFS §2.1.1.3

[check]

[check]

[check]

[check]

[check]

[check](1)

[check]

Geometry st_geomunion(Geometry, Geometry)

SFS §2.1.1.3 (renamed from union)

[check]

[check]

[times]

[check]

[check]

[check](1)

[check]

Geometry st_difference(Geometry, Geometry)

SFS §2.1.1.3

[check]

[check]

[check]

[check]

[check]

[check](1)

[check]

Geometry st_symdifference(Geometry, Geometry)

SFS §2.1.1.3

[check]

[check]

[check]

[check]

[check]

[check](1)

[check]

Common non-SFS functions

boolean st_dwithin(Geometry, Geometry, double)

Returns true if the geometries are within the specified distance of one another

[check]

[check]

[times]

[times]

[check]

[check]

[check]

Geometry st_transform(Geometry, int)

Returns a new geometry with its coordinates transformed to the SRID referenced by the integer parameter

[check]

[check]

[times]

[times]

[times]

[times]

[check]

Spatial st_aggregate Functions

Geometry st_extent(Geometry)

Returns a bounding box that bounds the set of returned geometries

[check]

[check]

[times]

[times]

[times]

[times]

[check]

(1) Argument Geometries need to have the same dimensionality.

Note that beyond the common spatial functions mentioned above, Hibernate may define additional spatial functions for each database dialect. These will be documented in the Database notes below.

Database notes

Postgresql

The Postgresql dialect has support for the Postgis spatial extension, but not the Geometric types mentioned in the Postgresql documentation.

In addition to the common spatial functions, the following functions are supported:

Table 2. Additional Postgis function support

Function

Purpose

Syntax

Postgis function operator

distance_2d

2D distance between two geometries

distance_2d(geom,geom)

<->

distance_2d_bbox

2D distance between the bounding boxes of tow geometries

distance_2d_bbox(geom,geom)

<#>

distance_cpa

3D distance between 2 trajectories

distance_cpa(geom,geom)

|=|

distance_centroid_nd

the n-D distance between the centroids of the bounding boxes of two geometries

distance_centroid_nd(geom,geom)

<<->>

MySQL

For more information, see this page in the MySQL reference guide (esp. the section Functions That Test Spatial Relations Between Geometry Objects)

Oracle 19c/21c/23ai

There is currently only support for the SDO_GEOMETRY type.

The SDOGeometryType requires access to an OracleConnection object when converting a geometry to SDO_GEOMETRY. In some environments, however, the OracleConnection is not available (e.g. because a Java EE container or connection pool proxy wraps the connection object in its own Connection implementation). A ConnectionFinder knows how to retrieve the OracleConnection from the wrapper or proxy Connection object that is passed into prepared statements. It can be configured with the hibernate.spatial.connection_finder property:

When the passed object is not already an OracleConnection, the default implementation will attempt to retrieve the OracleConnection by recursive reflection. It will search for methods that return Connection objects, execute these methods and check the result. If the result is of type OracleConnection the object is returned. Otherwise, it recurses on it.

In may cases, this strategy will suffice. If not, you can provide your own implementation of this interface on the classpath, and configure it in the hibernate.spatial.connection_finder property. Note that implementations must be thread-safe and have a default no-args constructor.

SQL Server

The GEOGRAPHY type is not currently supported.

CockroachDB

The dialect CockroachDialect supports the GEOMETRY type in CockroachDB v20.2 and later. The GEOGRAPHY type is currently not supported.

H2GIS

The H2Dialect supports H2GIS, a spatial extension of the H2 in-memory database. This dialect can be used as a replacement for the GeoDB dialect that was supported in previous versions. The major difference with GeoDB is that the GEOGRAPHY column type is currently not present in H2GIS.

DB2

The DB2SpatialDialect supports the spatial extensions of the DB2 LUW database. The dialect has been tested with DB2 LUW 11.1. The dialect does not support DB2 for z/OS or DB2 column-oriented databases.

In order to use the DB2 Hibernate Spatial capabilities, it is necessary to first execute the following SQL statements which will allow DB2 to accept Extended WellKnown Text (EWKT) data and return EWKT data. One way to do this is to copy these statements into a file such as ewkt.sql and execute it in a DB2 command window with a command such as db2 -tvf ewkt.sql.

create or replace function db2gse.asewkt(geometry db2gse.st_geometry)
returns clob(2G)
specific db2gse.asewkt1
language sql
deterministic
no external action
reads sql data
return 'srid=' || varchar(db2gse.st_srsid(geometry)) || ';' || db2gse.st_astext(geometry);

create or replace function db2gse.geomfromewkt(instring varchar(32000))
returns db2gse.st_geometry
specific db2gse.fromewkt1
language sql
deterministic
no external action
reads sql data
return db2gse.st_geometry(
substr(instring,posstr(instring,';')+1, length(instring) - posstr(instring,';')),
integer(substr(instring,posstr(instring,'=')+1,posstr(instring,';')-(posstr(instring,'=')+1))));

create transform for db2gse.st_geometry ewkt (
 from sql with function db2gse.asewkt(db2gse.st_geometry),
 to   sql with function db2gse.geomfromewkt(varchar(32000)) );

drop transform db2_program for db2gse.st_geometry;
create transform for db2gse.st_geometry db2_program (
 from sql with function db2gse.asewkt(db2gse.st_geometry),
 to   sql with function db2gse.geomfromewkt(varchar(32000)) );

Types

It suffices to declare a property as either a JTS or a Geolatte-geom Geometry and Hibernate Spatial will map it using the relevant type.

Here is an example using JTS:

Example 2. Type mapping
link:../../../../../../../../hibernate-spatial/src/test/java/org/hibernate/spatial/testing/SpatialTest.java[role=include]

We can now treat spatial geometries like any other type.

Example 3. Creating a Point
link:../../../../../../../../hibernate-spatial/src/test/java/org/hibernate/spatial/testing/SpatialTest.java[role=include]

Spatial Dialects defines many query functions that are available both in HQL and JPQL queries. Below we show how we could use the within function to find all objects within a given spatial extent or window.

Example 4. Querying the geometry
link:../../../../../../../../hibernate-spatial/src/test/java/org/hibernate/spatial/testing/SpatialTest.java[role=include]