hibernate-spatialgrails-4

How to use PostgisFunctions in hibernate-spatial to transform CRS geometry


Geometry field is being defined by org.locationtech.jts.geom thus in regards to spatial methods the one can implement following: covers, within, buffer, contains...(see Concrete Methods).
org.locationtech.jts.geomdoesn't provide a method for transforming CRS, however hibernate-spatial does(see hibernate-spatial dialect function support).

How do we call Postgis function e.g transform over hibernate-spatial?
As was stated in the comment of the PostgisPG95Dialect class:
Extends the {@code PostgreSQL95Dialect} to add support for the Postgis spatial types, functions and operators, however calling function either with PostgisPG95Dialect, PostgisFunctions or directly over geometry it's not found.

PostgreSQL95Dialect.transform(geometry,4326)
SpatialFunction.transform(geometry,4326)
PostgisFunctions.transform(geometry,4326)
geometry.transform(4326)

In case, when the geometry has to be mapped with org.hibernate.spatial.GeolatteGeometryType (see hibernate-spatial types) comes the following error( error with org.hibernate.spatial.JTSGeometryType is identical):

Caused by: org.hibernate.MappingException: Could not instantiate Type: org.hibernate.spatial.GeolatteGeometryType
at org.hibernate.type.TypeFactory.type(TypeFactory.java:113)
at org.hibernate.type.TypeFactory.byClass(TypeFactory.java:70)
at org.hibernate.type.TypeResolver.heuristicType(TypeResolver.java:126)
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:473)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:455)
at org.hibernate.mapping.Property.isValid(Property.java:227)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:624)
at org.hibernate.mapping.RootClass.validate(RootClass.java:267)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:351)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:464)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
at org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration.buildSessionFactory(HibernateMappingContextConfiguration.java:287)
at org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory.create(HibernateConnectionSourceFactory.java:86)
at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:39)
at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:23)
at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:64)
at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:52)
at org.grails.datastore.mapping.core.connections.ConnectionSourcesInitializer.create(ConnectionSourcesInitializer.groovy:24)
at org.grails.orm.hibernate.HibernateDatastore.<init>(HibernateDatastore.java:212)
at jdk.internal.reflect.GeneratedConstructorAccessor83.newInstance(Unknown Source)
atjava.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172)
... 127 common frames omitted
Caused by: java.lang.InstantiationException: org.hibernate.spatial.GeolatteGeometryType
at java.base/java.lang.Class.newInstance(Class.java:571)
at org.hibernate.type.TypeFactory.type(TypeFactory.java:105)
... 149 common frames omitted
Caused by: java.lang.NoSuchMethodException: org.hibernate.spatial.GeolatteGeometryType.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3350)
at java.base/java.lang.Class.newInstance(Class.java:556)
... 150 common frames omitted

Solution

  • It has been found out workaround solution direcly over hibernate sql.
    Hibernate-Spatial PostGIS e.g transform function can be called using Hibernate SQL syntax query over a Domain Class and its geometry field in Grails as following example:

    Geometry geometry4326 =  Parcel.executeQuery("select transform(geometry,4326) as geom from Parcel where id=1").first()
    

    Geometry field retains locationtech.jts definition.