diff --git a/.gitignore b/.gitignore index 3fcf6bfbd8..f4d9b9636d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,5 @@ ObjectStore /.nb-gradle/ # Additional databases used in local envs -databases/mysql/matrix.gradle -databases/mysql/resources/hibernate.properties - +databases/mysql/ +databases/postgis/ diff --git a/documentation/documentation.gradle b/documentation/documentation.gradle index 3d9e252c46..abc4aadc23 100644 --- a/documentation/documentation.gradle +++ b/documentation/documentation.gradle @@ -63,6 +63,7 @@ dependencies { testCompile( project(':hibernate-core') ) testCompile( project(':hibernate-entitymanager') ) testCompile( project(':hibernate-ehcache') ) + testCompile( project(':hibernate-spatial') ) testCompile( project(':hibernate-testing') ) testCompile( project(path: ':hibernate-entitymanager', configuration: 'tests') ) diff --git a/documentation/src/main/asciidoc/userguide/Hibernate_User_Guide.adoc b/documentation/src/main/asciidoc/userguide/Hibernate_User_Guide.adoc index 3e5c921a01..3f61f5700b 100644 --- a/documentation/src/main/asciidoc/userguide/Hibernate_User_Guide.adoc +++ b/documentation/src/main/asciidoc/userguide/Hibernate_User_Guide.adoc @@ -19,9 +19,10 @@ include::chapters/fetching/Fetching.adoc[] include::chapters/batch/Batching.adoc[] include::chapters/caching/Caching.adoc[] include::chapters/events/Events.adoc[] -include::chapters/query-hql/HQL.adoc[] -include::chapters/query-criteria/Criteria.adoc[] -include::chapters/query-native/Native.adoc[] +include::chapters/query/hql/HQL.adoc[] +include::chapters/query/criteria/Criteria.adoc[] +include::chapters/query/native/Native.adoc[] +include::chapters/query/spatial/Spatial.adoc[] include::chapters/multitenancy/Multi_Tenancy.adoc[] include::chapters/osgi/OSGi.adoc[] include::chapters/envers/Envers.adoc[] diff --git a/documentation/src/main/asciidoc/userguide/appendices/Legacy_Criteria.adoc b/documentation/src/main/asciidoc/userguide/appendices/Legacy_Criteria.adoc index b7bae38f2c..88e088c926 100644 --- a/documentation/src/main/asciidoc/userguide/appendices/Legacy_Criteria.adoc +++ b/documentation/src/main/asciidoc/userguide/appendices/Legacy_Criteria.adoc @@ -7,7 +7,7 @@ This appendix covers the legacy Hibernate `org.hibernate.Criteria` API, which sh New development should focus on the JPA javax.persistence.criteria.CriteriaQuery API. Eventually, Hibernate-specific criteria features will be ported as extensions to the JPA `javax.persistence.criteria.CriteriaQuery`. -For details on the JPA APIs, see <>. +For details on the JPA APIs, see <>. ==== Hibernate features an intuitive, extensible criteria query API. diff --git a/documentation/src/main/asciidoc/userguide/chapters/batch/Batching.adoc b/documentation/src/main/asciidoc/userguide/chapters/batch/Batching.adoc index 20f74b79cc..1f7bfbdaaa 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/batch/Batching.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/batch/Batching.adoc @@ -277,4 +277,4 @@ include::{sourcedir}/BatchTest.java[tags=batch-bulk-hql-insert-example] ---- ==== -This section is only a brief overview of HQL. For more information, see <>. +This section is only a brief overview of HQL. For more information, see <>. diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-criteria/Criteria.adoc b/documentation/src/main/asciidoc/userguide/chapters/query/criteria/Criteria.adoc similarity index 99% rename from documentation/src/main/asciidoc/userguide/chapters/query-criteria/Criteria.adoc rename to documentation/src/main/asciidoc/userguide/chapters/query/criteria/Criteria.adoc index 0cdd10e4f0..f96d032592 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/query-criteria/Criteria.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/query/criteria/Criteria.adoc @@ -1,6 +1,6 @@ [[criteria]] == Criteria -:sourcedir: ../../../../../test/java/org/hibernate/userguide/criteria +:sourcedir: ../../../../../../test/java/org/hibernate/userguide/criteria Criteria queries offer a type-safe alternative to HQL, JPQL and native SQL queries. diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/HQL.adoc b/documentation/src/main/asciidoc/userguide/chapters/query/hql/HQL.adoc similarity index 99% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/HQL.adoc rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/HQL.adoc index 6508f58219..91f5e9ea3e 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/query-hql/HQL.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/query/hql/HQL.adoc @@ -1,7 +1,7 @@ [[hql]] == HQL and JPQL -:modeldir: ../../../../../main/java/org/hibernate/userguide/model -:sourcedir: ../../../../../test/java/org/hibernate/userguide/hql +:modeldir: ../../../../../../main/java/org/hibernate/userguide/model +:sourcedir: ../../../../../../test/java/org/hibernate/userguide/hql :extrasdir: extras The Hibernate Query Language (HQL) and Java Persistence Query Language (JPQL) are both object model focused query languages similar in nature to SQL. @@ -9,7 +9,7 @@ JPQL is a heavily-inspired-by subset of HQL. A JPQL query is always a valid HQL query, the reverse is not true however. Both HQL and JPQL are non-type-safe ways to perform query operations. -Criteria queries offer a type-safe approach to querying. See <> for more information. +Criteria queries offer a type-safe approach to querying. See <> for more information. [[query-api]] === Query API diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/predicate_in_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/predicate_in_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/predicate_in_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/predicate_in_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/predicate_like_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/predicate_like_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/predicate_like_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/predicate_like_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/root_entity_ref_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/root_entity_ref_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/root_entity_ref_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/root_entity_ref_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/searched_case_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/searched_case_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/searched_case_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/searched_case_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/simple_case_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/simple_case_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/simple_case_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/simple_case_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/statement_delete_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/statement_delete_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/statement_delete_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/statement_delete_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/statement_insert_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/statement_insert_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/statement_insert_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/statement_insert_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/statement_select_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/statement_select_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/statement_select_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/statement_select_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/statement_update_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/statement_update_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/statement_update_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/statement_update_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/substring_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/substring_bnf.txt similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-hql/extras/substring_bnf.txt rename to documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/substring_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-native/Native.adoc b/documentation/src/main/asciidoc/userguide/chapters/query/native/Native.adoc similarity index 99% rename from documentation/src/main/asciidoc/userguide/chapters/query-native/Native.adoc rename to documentation/src/main/asciidoc/userguide/chapters/query/native/Native.adoc index 0512afc62a..0ff7dcf6c5 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/query-native/Native.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/query/native/Native.adoc @@ -1,7 +1,7 @@ [[sql]] == Native SQL Queries -:modeldir: ../../../../../main/java/org/hibernate/userguide/model -:sourcedir: ../../../../../test/java/org/hibernate/userguide/sql +:modeldir: ../../../../../../main/java/org/hibernate/userguide/model +:sourcedir: ../../../../../../test/java/org/hibernate/userguide/sql :extrasdir: extras You may also express queries in the native SQL dialect of your database. diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-native/extras/sql-hibernate-entity-associations-query-many-to-one-join-example.sql b/documentation/src/main/asciidoc/userguide/chapters/query/native/extras/sql-hibernate-entity-associations-query-many-to-one-join-example.sql similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-native/extras/sql-hibernate-entity-associations-query-many-to-one-join-example.sql rename to documentation/src/main/asciidoc/userguide/chapters/query/native/extras/sql-hibernate-entity-associations-query-many-to-one-join-example.sql diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-native/extras/sql-hibernate-entity-associations-query-one-to-many-join-example.sql b/documentation/src/main/asciidoc/userguide/chapters/query/native/extras/sql-hibernate-entity-associations-query-one-to-many-join-example.sql similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-native/extras/sql-hibernate-entity-associations-query-one-to-many-join-example.sql rename to documentation/src/main/asciidoc/userguide/chapters/query/native/extras/sql-hibernate-entity-associations-query-one-to-many-join-example.sql diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-native/extras/sql-jpa-entity-associations-query-many-to-one-join-example.sql b/documentation/src/main/asciidoc/userguide/chapters/query/native/extras/sql-jpa-entity-associations-query-many-to-one-join-example.sql similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-native/extras/sql-jpa-entity-associations-query-many-to-one-join-example.sql rename to documentation/src/main/asciidoc/userguide/chapters/query/native/extras/sql-jpa-entity-associations-query-many-to-one-join-example.sql diff --git a/documentation/src/main/asciidoc/userguide/chapters/query-native/extras/sql-jpa-entity-associations-query-one-to-many-join-example.sql b/documentation/src/main/asciidoc/userguide/chapters/query/native/extras/sql-jpa-entity-associations-query-one-to-many-join-example.sql similarity index 100% rename from documentation/src/main/asciidoc/userguide/chapters/query-native/extras/sql-jpa-entity-associations-query-one-to-many-join-example.sql rename to documentation/src/main/asciidoc/userguide/chapters/query/native/extras/sql-jpa-entity-associations-query-one-to-many-join-example.sql diff --git a/documentation/src/main/asciidoc/userguide/chapters/query/spatial/Spatial.adoc b/documentation/src/main/asciidoc/userguide/chapters/query/spatial/Spatial.adoc new file mode 100644 index 0000000000..c197762051 --- /dev/null +++ b/documentation/src/main/asciidoc/userguide/chapters/query/spatial/Spatial.adoc @@ -0,0 +1,269 @@ +[[spatial]] +== Spatial +:sourcedir: ../../../../../../test/java/org/hibernate/userguide/spatial +:extrasdir: extras + +[[spatial-overview]] +=== 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 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, and the supported databases are: Oracle 10g/11g, PostgreSql/PostGIS, MySQL, Microsoft SQL Server and H2/GeoDB, +yet, not all databases support all the functions defined by Hibernate Spatial. + +Hibernate Spatial uses the Java Topology Suite (JTS) as its geometry model. +JTS is an implementation of the OpenGIS Simple Features Implementation Specification for SQLv. 1.1 (SFS). +This specification is implemented in most RDBMS with spatial data support. +It is also a direct precursor to SQL/MM Part 3: Spatial (ISO/IEC 13249-3). + +The SFS specification defines a set of functions on geometries. +Hibernate Spatial makes a subset of these functions available in HQL and in the Criteria Query API. + +[[spatial-configuration]] +=== Configuration + +Hibernate Spatial requires some configuration prior to start using it. + +[[spatial-configuration-dependency]] +==== Dependency + +You need to include the `hibernate-spatial` dependency in your build environment. +For Maven, you need to add the following dependency: + +[[spatial-configuration-maven-example]] +.Maven dependency +==== +[source,xml] +---- + + org.hibernate + hibernate-spatial + ${hibernate.version} + +---- +==== + +[[spatial-configuration-dialect]] +==== Dialects + +Hibernate Spatial extends the Hibernate ORM dialects so that the spatial functions of the database are made available within HQL and JPQL. +So, for instance, instead of using the `PostgreSQL82Dialect`, we use the Hibernate Spatial extension of that dialect which is the `PostgisDialect`. + +[[spatial-configuration-dialect-example]] +.Specifying a spatial dialect +==== +[source,xml] +---- + +---- +==== + +Not all databases support all the functions defined by Hibernate Spatial. +The table below provides an overview of the functions provided by each database. + +:yes: icon:check[role="green"] +:no: icon:times[role="red"] +[[spatial-configuration-dialect-features]] +.Hibernate Spatial dialect function support +[cols=",,,,,," |options="header",] +|================================ +|Function | Description | PostgresSQL | Oracle 10g/11g | MySQL | SQLServer | GeoDB (H2) +|Basic functions on Geometry | | | | | | +|`int dimension(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} +|`String geometrytype(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} +|`int srid(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} +|`Geometry envelope(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} +|`String astext(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} +|`byte[] asbinary(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean isempty(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean issimple(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {yes} | {yes} | {yes} +|`Geometry boundary(Geometry)` | SFS §2.1.1.1 | {yes} | {yes} | {no} | {yes} | {yes} +|Functions for testing Spatial Relations between geometric objects | | | | | | +|`boolean equals(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean disjoint(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean intersects(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean touches(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean crosses(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean within(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean contains(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean overlaps(Geometry, Geometry)` | SFS §2.1.1.2 | {yes} | {yes} | {yes} | {yes} | {yes} +|`boolean relate(Geometry, Geometry, String)` | SFS §2.1.1.2 | {yes} | {yes} | {no} | {yes} | {yes} +|Functions that support Spatial Analysis | | | | | | +|`double distance(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} +|`Geometry buffer(Geometry, double)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} +|`Geometry convexhull(Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} +|`Geometry intersection(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} +|`Geometry geomunion(Geometry, Geometry)` | SFS §2.1.1.3 (renamed from union) | {yes} | {yes} | {no} | {yes} | {yes} +|`Geometry difference(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} +|`Geometry symdifference(Geometry, Geometry)` | SFS §2.1.1.3 | {yes} | {yes} | {no} | {yes} | {yes} +|Common non-SFS functions | | | | | | +|`boolean dwithin(Geometry, Geometry, double)` | Returns true if the geometries are within the specified distance of one another | {yes} | {yes} | {no} | {no} | {yes} +|`Geometry transform(Geometry, int)` | Returns a new geometry with its coordinates transformed to the SRID referenced by the integer parameter | {yes} | {yes} | {no} | {no} | {no} +|Spatial aggregate Functions | | | | | | +|`Geometry extent(Geometry)` | Returns a bounding box that bounds the set of returned geometries | {yes} | {yes} | {no} | {no} | {no} +|================================ + +[[spatial-configuration-dialect-postgis]] +Postgis:: +For Postgis from versions 1.3 and later, the best dialect to use is `org.hibernate.spatial.dialect.postgis.PostgisDialect`. ++ +This translates the HQL spatial functions to the Postgis SQL/MM-compliant functions. +For older, pre v1.3 versions of Postgis, which are not SQL/MM compliant, the dialect `org.hibernate.spatial.dialect.postgis.PostgisNoSQLMM` is provided. ++ +This dialect depends on the JDBC extensions in postgis.jar (see the http://postgis.net/docs/postgis_installation.html#id336398[Postgis documentation]). + +[IMPORTANT] +==== +Beware of classpath problems in a Java EE containers where the JDBC drivers live in a different classpath than the Postgis JDBC extensions and/or Hibernate Spatial. +For JBoss, some users found https://gist.github.com/bjornharrtell/3054462[this post] helpful. +==== +[[spatial-configuration-dialect-mysql]] +MySQL:: +There are several dialects for MySQL: + +`MySQLSpatialDialect`::: + a spatially-extended version of Hibernate `MySQLDialect` +`MySQLSpatialInnoDBDialect`::: + a spatially-extended version of Hibernate `MySQLInnoDBDialect` +`MySQLSpatial56Dialect`::: + a spatially-extended version of Hibernate `MySQL5DBDialect`. +`MySQLSpatial5InnoDBDialect`::: + the same as `MySQLSpatial56Dialect`, but with support for the InnoDB storage engine. + +[NOTE] +==== +MySQL versions before 5.6.1 had only limited support for spatial operators. +Most operators only took account of the minimum bounding rectangles (MBR) of the geometries, and not the geometries themselves. + +This changed in version 5.6.1 were MySQL introduced `ST_*` spatial operators. +The dialects `MySQLSpatial56Dialect` and `MySQLSpatial5InnoDBDialect` use these newer, more precise operators. + +These dialects may therefore produce results that differ from that of the other spatial dialects. + +For more information see this page in the MySQL reference guide (esp. the section https://dev.mysql.com/doc/refman/5.7/en/spatial-relation-functions.html[Functions That Test Spatial Relations Between Geometry Objects]) +==== +[[spatial-configuration-dialect-oracle]] +Oracle10g/11g:: + +There is currently only one Oracle spatial dialect: `OracleSpatial10gDialect` which extends the Hibernate dialect `Oracle10gDialect`. +This dialect has been tested on both Oracle 10g and Oracle 11g with the `SDO_GEOMETRY` spatial database type. ++ +This dialect is the only dialect that can be configured using these Hibernate properties: ++ +`hibernate.spatial.connection_finder`::: +the fully-qualified classname for the Connection finder for this Dialect (see below). + +.The `ConnectionFinder` interface +[NOTE] +==== +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. + +The default implementation will, when the passed object is not already an `OracleConnection`, 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 class path, and configure it in the `hibernate.spatial.connection_finder` property. +Note that implementations must be thread-safe and have a default no-args constructor. +==== + +`hibernate.spatial.ogc_strict`::: true to use the OGC-compliant functions on SDO_GEOMETRY (see below) +.OGC Compliance Setting +[NOTE] +==== +The Oracle Spatial dialect can be configured to run in either OGC strict or non-strict mode. +In OGC strict mode, the Open Geospatial compliant functions of Oracle Spatial are used in spatial operations (they exists in Oracle 10g, but are not documented). In non-strict mode the usual Oracle Spatial functions are used directly, and mimic the OGC semantics.The default is OGC strict mode. +You can change this to non-strict mode by setting the hibernate.spatial.ogc_strict property to false. + +Note that changing from strict to non-strict mode changes the semantics of the spatial operation. +We have attempted to implement the OGC semantics as well we could using the standard Oracle Spatial operators, but this was not possible in all cases. +On the plus side, non-strict mode should be faster in most cases. +==== + +SQL Server:: +The dialect `SqlServer2008Dialect` supports the `GEOMETRY` type in SQL Server 2008 and later. + +[NOTE] +==== +The `GEOGRAPHY` type is not currently supported. +==== + +GeoDB (H2):: +The `GeoDBDialect` supports the GeoDB a spatial extension of the H2 in-memory database. +[NOTE] +==== +The dialect has been tested with GeoDB version 0.7 +==== + +[[spatial-types]] +=== Types + +Hibernate Spatial comes with the following types: + +jts_geometry:: + Handled by `org.hibernate.spatial.JTSGeometryType` it maps a database geometry column type to a `com.vividsolutions.jts.geom.Geometry` entity property type. +geolatte_geometry:: + Handled by `org.hibernate.spatial.GeolatteGeometryType`, it maps a database geometry column type to a `org.geolatte.geom.Geometry` entity property type. + +The following entity uses the `jts_geometry` to map the PostgreSQL geometry type to a `com.vividsolutions.jts.geom.Point`. + +[[spatial-types-mapping-example]] +.Type mapping +==== +[source, JAVA, indent=0] +---- +include::{sourcedir}/SpatialTest.java[tags=spatial-types-mapping-example] +---- +==== + +When creating such entity: + +[[spatial-types-point-creation-example]] +.Creating a Point +==== +[source, JAVA, indent=0] +---- +include::{sourcedir}/SpatialTest.java[tags=spatial-types-point-creation-example] +---- +==== + +Hibernate generates the following SQL statement: + +[[spatial-types-point-creation-example]] +.Creating a Point +==== +[source, SQL, indent=0] +---- +include::{extrasdir}/spatial-types-point-creation-example.sql[] +---- +==== + +Hibernate Spatial defines many query functions that are available both in HQL and JPQL queries. + +[[spatial-types-query-example]] +.Querying the geometry +==== +[source, SQL, indent=0] +---- +include::{sourcedir}/SpatialTest.java[tags=spatial-types-query-example] +---- +==== + +This JPQL query generates the following SQL statement: + +[[spatial-types-sql-query-example]] +.Underlying SQL query +==== +[source, SQL, indent=0] +---- +include::{extrasdir}/spatial-types-sql-query-example.sql[] +---- +==== diff --git a/documentation/src/main/asciidoc/userguide/chapters/query/spatial/extras/spatial-types-point-creation-example.sql b/documentation/src/main/asciidoc/userguide/chapters/query/spatial/extras/spatial-types-point-creation-example.sql new file mode 100644 index 0000000000..9907b77740 --- /dev/null +++ b/documentation/src/main/asciidoc/userguide/chapters/query/spatial/extras/spatial-types-point-creation-example.sql @@ -0,0 +1,4 @@ +INSERT INTO + Event (location, name, id) +VALUES + ('POINT (10 5)', 'Hibernate ORM presentation', 1) \ No newline at end of file diff --git a/documentation/src/main/asciidoc/userguide/chapters/query/spatial/extras/spatial-types-sql-query-example.sql b/documentation/src/main/asciidoc/userguide/chapters/query/spatial/extras/spatial-types-sql-query-example.sql new file mode 100644 index 0000000000..3eeba650e0 --- /dev/null +++ b/documentation/src/main/asciidoc/userguide/chapters/query/spatial/extras/spatial-types-sql-query-example.sql @@ -0,0 +1,6 @@ +select + e.id as id1_0_, + e.location as location2_0_, + e.name as name3_0_ +from Event e +where st_within(e.location, 'POLYGON ((1 1, 20 1, 20 20, 1 20, 1 1))') = true \ No newline at end of file diff --git a/documentation/src/test/java/org/hibernate/userguide/bootstrap/BootstrapTest.java b/documentation/src/test/java/org/hibernate/userguide/bootstrap/BootstrapTest.java index ea7668bd86..3a46ed3cf8 100644 --- a/documentation/src/test/java/org/hibernate/userguide/bootstrap/BootstrapTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/bootstrap/BootstrapTest.java @@ -13,6 +13,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import javax.persistence.AttributeConverter; import javax.persistence.Entity; import javax.persistence.EntityManagerFactory; import javax.persistence.Id; @@ -155,6 +156,17 @@ public class BootstrapTest { } { + AttributeConverter myAttributeConverter = new AttributeConverter() { + @Override + public Object convertToDatabaseColumn(Object attribute) { + return null; + } + + @Override + public Object convertToEntityAttribute(Object dbData) { + return null; + } + } ; //tag::bootstrap-native-metadata-builder-example[] ServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().build(); @@ -170,6 +182,9 @@ public class BootstrapTest { // specify the schema name to use for tables, etc when none is explicitly specified metadataBuilder.applyImplicitSchemaName( "my_default_schema" ); + // specify a custom Attribute Converter + metadataBuilder.applyAttributeConverter( myAttributeConverter ); + Metadata metadata = metadataBuilder.build(); //end::bootstrap-native-metadata-builder-example[] } diff --git a/documentation/src/test/java/org/hibernate/userguide/spatial/SpatialTest.java b/documentation/src/test/java/org/hibernate/userguide/spatial/SpatialTest.java new file mode 100644 index 0000000000..e41e85480c --- /dev/null +++ b/documentation/src/test/java/org/hibernate/userguide/spatial/SpatialTest.java @@ -0,0 +1,126 @@ +/* + * 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.userguide.spatial; + +import javax.persistence.Entity; +import javax.persistence.Id; + +import org.hibernate.annotations.Type; +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; +import org.hibernate.spatial.dialect.postgis.PostgisDialect; + +import org.hibernate.testing.RequiresDialect; +import org.junit.Test; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import static org.junit.Assert.assertEquals; + +import static org.hibernate.userguide.util.TransactionUtil.doInJPA; + +/** + * @author Vlad Mihalcea + */ +@RequiresDialect(PostgisDialect.class) +public class SpatialTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + Event.class, + }; + } + + @Test + public void test() { + Long addressId = doInJPA( this::entityManagerFactory, entityManager -> { + try { + //tag::spatial-types-point-creation-example[] + Event event = new Event(); + event.setId( 1L); + event.setName( "Hibernate ORM presentation"); + event.setLocation( (Point) new WKTReader().read( "POINT(10 5)")); + + entityManager.persist( event ); + //end::spatial-types-point-creation-example[] + return event.getId(); + } catch (ParseException e) { + throw new RuntimeException(e); + } + }); + + doInJPA( this::entityManagerFactory, entityManager -> { + Event event = entityManager.find( Event.class, addressId); + Coordinate coordinate = event.getLocation().getCoordinate(); + assertEquals( 10.0d, coordinate.getOrdinate( Coordinate.X), 0.1); + assertEquals( 5.0d, coordinate.getOrdinate( Coordinate.Y), 0.1); + }); + + doInJPA( this::entityManagerFactory, entityManager -> { + try { + //tag::spatial-types-query-example[] + Event event = entityManager.createQuery( + "select e " + + "from Event e " + + "where within(e.location, :filter) = true", Event.class) + .setParameter("filter", new WKTReader().read( "POLYGON((1 1,20 1,20 20,1 20,1 1))")) + .getSingleResult(); + //end::spatial-types-query-example[] + Coordinate coordinate = event.getLocation().getCoordinate(); + assertEquals( 10.0d, coordinate.getOrdinate( Coordinate.X), 0.1); + assertEquals( 5.0d, coordinate.getOrdinate( Coordinate.Y), 0.1); + } + catch (ParseException e) { + throw new RuntimeException(e); + } + }); + } + + //tag::spatial-types-mapping-example[] + @Entity(name = "Event") + public static class Event { + + @Id + private Long id; + + private String name; + + @Type(type = "jts_geometry") + private Point location; + + //Getters and setters are omitted for brevity + //end::spatial-types-mapping-example[] + 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; + } + //tag::spatial-types-mapping-example[] + } + //end::spatial-types-mapping-example[] +} diff --git a/documentation/src/test/resources/log4j.properties b/documentation/src/test/resources/log4j.properties index e2f824168b..222ed33e39 100644 --- a/documentation/src/test/resources/log4j.properties +++ b/documentation/src/test/resources/log4j.properties @@ -25,7 +25,7 @@ log4j.logger.org.hibernate.reflection=info log4j.logger.org.hibernate.SQL=debug ### log JDBC bind parameters ### -log4j.logger.org.hibernate.type=info +log4j.logger.org.hibernate.type.descriptor.sql=trace ### log schema export/update ### log4j.logger.org.hibernate.tool.hbm2ddl=info