Introduction to Hibernate Spatial

I just announced the new Spring 5 modules in REST With Spring:

1. Introduction

In this article, we’ll have a look a the spatial extension of Hibernate, hibernate-spatial.

Starting with version 5, Hibernate Spatial provides a standard interface for working with geographic data.

2. Background on Hibernate Spatial

Geographic data includes representation of entities like a Point, Line, Polygon. Such data types aren’t a part of the JDBC specification, hence the JTS (JTS Topology Suite) has become a standard for representing spatial data types.

Apart from JTS, Hibernate spatial also supports Geolatte-geom – a recent library that has some features that aren’t available in JTS.

Both libraries are already included in the hibernate-spatial project. Using one library over other is simply a question of from which jar we’re importing data types.

Although Hibernate spatial supports different databases like Oracle, MySQL, PostgreSQLql/PostGIS, and a few others, the support for the database specific functions isn’t uniform.

It’s better to refer to the latest Hibernate documentation to check the list of functions for which hibernate provides support for a given database.

In this article, we’ll be using an in-memory Mariadb4j – which maintains the full functionality of MySQL.

The configuration for Mariadb4j and MySql are similar, even the mysql-connector library works for both of these databases.

3. Maven Dependencies

Let’s have a look at the Maven dependencies required for setting up a simple hibernate-spatial project:

4. Configuring Hibernate Spatial

The only thing that is specific to hibernate-spatial is the MySQL56SpatialDialect dialect. This dialect extends the MySQL55Dialect dialect and provides additional functionality related to the spatial data types.

The code specific to loading the property file, creating a SessionFactory, and instantiating a Mariadb4j instance, is same as in a standard hibernate project.

5. Understanding the Geometry Type

Geometry is the base type for all the spatial types in JTS. This means that other types like Point, Polygon, and others extend from Geometry. The Geometry type in java corresponds to the GEOMETRY type in MySql as well.

By parsing a String representation of the type, we get an instance of Geometry. A utility class WKTReader provided by JTS can be used to convert any well-known text representation to a Geometry type:

Calling toString() on a Point returns the WKT representation of a Point. This is because the Geometry class overrides the toString() method and internally uses WKTWriter, a complimentary class to WKTReader that we saw earlier.

Once we run this test, hibernate will create PointEntity table for us.

A circle is represented by a finite set of points specified by the setNumPoints() method. The radius is doubled before calling the setSize() method as we need to draw the circle around the center, in both the directions.

Let’s now move forward and see how to fetch the points within a given radius:

Hibernate maps its within() function to the ST_WITHIN() function of MySql.

An interesting observation here is that the Point (3, 4) falls exactly on the circle. Still, the query doesn’t return this point. This is because the within() function returns true only if the given Geometry is completely within another Geometry.

7.2. ST_TOUCHES() Example

Here, we’ll present an example that inserts a set of Polygons in the database and select the Polygons that are adjacent to a given Polygon. Let’s have a quick look at the PolygonEntity class: