Spring Data repository and native query with Geometry return type

Spring Data repository and native query with Geometry return type



I'm creating a project that uses some spatial queries.
I use Spring boot with spring data repositories and PostgreSQL with PostGIS extension as database.



I created this repository:


import com.vividsolutions.jts.geom.Geometry;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface AreaRepository extends CrudRepository<Area, Long>

/*
extra queries for Area here
*/

@Query(value="select st_intersection(" +
":base_layer ," +
":filter_layer" +
")", nativeQuery = true)
Geometry geometryIntersectGeometry(@Param("base_layer") Geometry baseGeometry,@Param("filter_layer") Geometry filterGeometry);




It contains some queries for the Area entity. I also want to use some PostGIS functions to do some calculations, so I created geometryIntersectGeometry to call the st_intersection function from PostGis, this should return a geometry.



I set the hibernate dialect to PostGIS in the settings:


spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/test_db
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect = org.hibernate.spatial.dialect.postgis.PostgisDialect



And I have the dependencies for hibernate spatial:


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>$hibernate.version</version>
</dependency>
...



Calling the geometryIntersectGeometry function results in an error:


No Dialect mapping for JDBC type: 1111; nested exception is org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111,



How do I tell JPA/Spring Data to map the geometry (PostGIS type) response to a Geometry(com.vividsolutions.jts.geom.Geometry) object?




3 Answers
3



Have you added Hibernate Spatial?


<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>$hibernate.version</version>
</dependency>



This has support for GIS data: http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#spatial






yes I know, I have the dependancy. Sorry will add dependancies to the question.

– Bart
Sep 14 '18 at 11:36






Have a look at how to register types in Hibernate Dialect vladmihalcea.com/hibernate-no-dialect-mapping-for-jdbc-type

– Simon Martinelli
Sep 14 '18 at 12:09



Managed to fix it by writing a custom implementation of the repository and register the type (thx Simon Martinelli)



repository:


import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface AreaRepository extends CrudRepository<Area, Long>, AreaGisRepository

/*
extra queries for Area here
*/




interface:


import com.vividsolutions.jts.geom.Geometry;

public interface AreaGisRepository

Geometry geometryIntersectGeometry(Geometry baseGeometry, Geometry filterGeometry);



and implementation:


import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.spatial.dialect.postgis.PGGeometryTypeDescriptor;
import org.springframework.beans.factory.annotation.Autowired;

import javax.persistence.EntityManager;

public class AreaGisRepositoryImpl implements AreaGisRepository

private EntityManager entityManager;

@Autowired
public AreaGisRepositoryImpl(EntityManager entityManager)
this.entityManager = entityManager;


@Override
public Geometry geometryIntersectGeometry(Geometry baseGeometry, Geometry filterGeometry)
return (Geometry) entityManager
.createNativeQuery(
"select st_intersection(:base_layer , :filter_layer) as geom")
.setParameter("base_layer", baseGeometry)
.setParameter("filter_layer", filterGeometry)
.unwrap(org.hibernate.query.NativeQuery.class)
.addScalar("geom", new JTSGeometryType(PGGeometryTypeDescriptor.INSTANCE))
.getSingleResult();





It works perfect, but I now have a hard coded dependency on Postgis (not likely we will use something else, but ...)



I think there is a simpler way to get this done. Hibernate Spatial registers a number of spatial functions for use in HQL/JQL. So the following should work


@Query(value="select intersection(" +
":base_layer ," +
":filter_layer" +
")")
Geometry geometryIntersectGeometry(@Param("base_layer") Geometry baseGeometry,@Param("filter_layer") Geometry filterGeometry);



See the documentation for a list of functions available in the Spatial Dialects.






Hi Karel, when I try that, it raises an exception: Caused by: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode -[METHOD_CALL] MethodNode: '(' +-[METHOD_NAME] IdentNode: 'intersection' originalText=intersection -[EXPR_LIST] SqlNode: 'exprList' +-[NAMED_PARAM] ParameterNode: '?' name=base_layer, expectedType=null -[NAMED_PARAM] ParameterNode: '?' name=filter_layer, expectedType=null [select intersection(:base_layer ,:filter_layer)]

– Bart
Sep 17 '18 at 8:01







I tried it myself, and discovered two problems. The first is the "no data type for node" problem. This can be resolved by using an expression like this: 'select intersection( cast( :base as geolatte_geometry ), :test)' (the cast helps Hibernate to resolve the return type). The second problem is that HQL/JPQL requires a mapped entity. Can't see a good solution for this second problem. So your fix seems to be the best.

– Karel Maesen
Sep 18 '18 at 20:46



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)