From 216e61fc9bc99cd4958fff9696aab14ac81a04cb Mon Sep 17 00:00:00 2001 From: Vlad Mihalcea Date: Tue, 23 May 2017 16:10:00 +0300 Subject: [PATCH] HHH-11764 - JTS geometry being bound to byte array instead of PGgeometry --- databases.gradle | 2 +- .../userguide/spatial/SpatialTest.java | 5 +- .../dialect/postgis/PostgisFunctions.java | 29 ++++- .../dialects/postgis/PostgisBufferTest.java | 115 ++++++++++++++++++ 4 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 hibernate-spatial/src/test/java/org/hibernate/spatial/testing/dialects/postgis/PostgisBufferTest.java diff --git a/databases.gradle b/databases.gradle index 3656b6844f..2722456c4f 100644 --- a/databases.gradle +++ b/databases.gradle @@ -52,7 +52,7 @@ ext { 'jdbc.url' : 'jdbc:mariadb://127.0.0.1/hibernate_orm_test' ], postgis : [ - 'db.dialect' : 'org.hibernate.spatial.dialect.postgis.PostgisDialect', + 'db.dialect' : 'org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect', 'jdbc.driver': 'org.postgresql.Driver', 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', diff --git a/documentation/src/test/java/org/hibernate/userguide/spatial/SpatialTest.java b/documentation/src/test/java/org/hibernate/userguide/spatial/SpatialTest.java index c6618e0695..70b55cfe13 100644 --- a/documentation/src/test/java/org/hibernate/userguide/spatial/SpatialTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/spatial/SpatialTest.java @@ -11,6 +11,7 @@ import javax.persistence.Id; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.spatial.dialect.postgis.PostgisDialect; +import org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect; import org.hibernate.testing.RequiresDialect; import org.junit.Test; @@ -30,10 +31,10 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; /** * @author Vlad Mihalcea */ -@RequiresDialect(PostgisDialect.class) +@RequiresDialect(PostgisPG95Dialect.class) public class SpatialTest extends BaseEntityManagerFunctionalTestCase { - GeometryFactory geometryFactory = new GeometryFactory(); + private GeometryFactory geometryFactory = new GeometryFactory(); @Override protected Class[] getAnnotatedClasses() { diff --git a/hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/postgis/PostgisFunctions.java b/hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/postgis/PostgisFunctions.java index b0ae2d4b6e..c128d90503 100644 --- a/hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/postgis/PostgisFunctions.java +++ b/hibernate-spatial/src/main/java/org/hibernate/spatial/dialect/postgis/PostgisFunctions.java @@ -139,9 +139,7 @@ class PostgisFunctions extends SpatialFunctionsRegistry { ) ); put( - "buffer", new StandardSQLFunction( - "st_buffer" - ) + "buffer", new BufferFunction() ); put( "convexhull", new StandardSQLFunction( @@ -201,4 +199,29 @@ class PostgisFunctions extends SpatialFunctionsRegistry { return rendered + "::geometry"; } } + + private static class BufferFunction extends StandardSQLFunction { + + public BufferFunction() { + super( "st_buffer" ); + } + + @Override + public String render( + Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) { + final StringBuilder buf = new StringBuilder(); + buf.append( getName() ).append( '(' ); + for ( int i = 0; i < arguments.size(); i++ ) { + buf.append( arguments.get( i ) ); + if( i == 0 ) { + buf.append( "::geometry" ); + } + if ( i < arguments.size() - 1 ) { + buf.append( ", " ); + } + } + return buf.append( ")::geometry" ).toString(); + } + } + } diff --git a/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/dialects/postgis/PostgisBufferTest.java b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/dialects/postgis/PostgisBufferTest.java new file mode 100644 index 0000000000..cb16562253 --- /dev/null +++ b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/dialects/postgis/PostgisBufferTest.java @@ -0,0 +1,115 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.spatial.testing.dialects.postgis; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.Id; + +import org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect; + +import org.hibernate.testing.RequiresDialect; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; + +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.assertEquals; + +/** + * @author Vlad Mihalcea + */ +@RequiresDialect(PostgisPG95Dialect.class) +public class PostgisBufferTest extends BaseCoreFunctionalTestCase { + + private GeometryFactory geometryFactory = new GeometryFactory(); + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + Event.class, + }; + } + + @Test + public void test() { + Long addressId = doInHibernate( this::sessionFactory, session -> { + Event event = new Event(); + event.setId( 1L); + event.setName( "Hibernate ORM presentation"); + Point point = geometryFactory.createPoint( new Coordinate( 10, 5 ) ); + event.setLocation( point ); + + session.persist( event ); + return event.getId(); + }); + + doInHibernate( this::sessionFactory, session -> { + Coordinate [] coordinates = new Coordinate[] { + new Coordinate(1,1), new Coordinate(20,1), new Coordinate(20,20), + new Coordinate(1,20), new Coordinate(1,1) + }; + Polygon window = geometryFactory.createPolygon( coordinates ); + + List events = session.createQuery( + "select e " + + "from Event e " + + "where buffer(:window, 100) is not null", Event.class) + .setParameter("window", window) + .getResultList(); + + assertEquals(1, events.size()); + + List locations = session.createQuery( + "select buffer(e.location, 10) " + + "from Event e ", Geometry.class) + .getResultList(); + + assertEquals(1, locations.size()); + }); + } + +@Entity(name = "Event") +public static class Event { + + @Id + private Long id; + + private String name; + + private Point location; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Point getLocation() { + return location; + } + + public void setLocation(Point location) { + this.location = location; + } +} +}