diff --git a/.github/workflows/contributor-build.yml b/.github/workflows/contributor-build.yml index 9a549710f3..dbdb5d6e2d 100644 --- a/.github/workflows/contributor-build.yml +++ b/.github/workflows/contributor-build.yml @@ -41,10 +41,19 @@ jobs: experimental: true - rdbms: mssql experimental: true +# Running with HANA requires at least 8GB memory just for the database, which we don't have on GH Actions runners +# - rdbms: hana +# experimental: true steps: - uses: actions/checkout@v2 + with: + persist-credentials: false - name: Reclaim Disk Space run: .github/ci-prerequisites.sh + - name: Start database + env: + RDBMS: ${{ matrix.rdbms }} + run: ci/database-start.sh - name: Set up Java 8 uses: actions/setup-java@v1 with: @@ -86,6 +95,8 @@ jobs: continue-on-error: true steps: - uses: actions/checkout@v2 + with: + persist-credentials: false - name: Set up Java 11 uses: actions/setup-java@v1 with: @@ -117,4 +128,4 @@ jobs: ./**/target/reports/tests/ ./**/target/reports/checkstyle/ - name: Omit produced artifacts from build cache - run: ./ci/before-cache.sh \ No newline at end of file + run: ./ci/before-cache.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0418e1966c..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,56 +0,0 @@ -dist: trusty -language: java -script: - - ./ci/build-travis.sh -before_cache: - - ./ci/before-cache.sh -cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ -matrix: - fast_finish: true - include: - - env: RDBMS=h2 - jdk: oraclejdk8 - sudo: required -# - env: RDBMS=derby -# jdk: oraclejdk8 -# sudo: required -# - env: RDBMS=mariadb -# jdk: oraclejdk8 -# sudo: true -# services: -# - docker -# - env: RDBMS=postgresql -# jdk: oraclejdk8 -# sudo: true -# services: -# - docker -# - env: RDBMS=oracle -# jdk: oraclejdk8 -# sudo: true -# services: -# - docker -# - env: RDBMS=db2 -# jdk: oraclejdk8 -# sudo: true -# services: -# - docker -# - env: RDBMS=mssql -# jdk: oraclejdk8 -# sudo: true -# services: -# - docker - - env: JDK=11 - install: - - curl -L -o install-jdk.sh https://github.com/sormuras/bach/raw/master/install-jdk.sh - - source ./install-jdk.sh --target ./openjdk11 --url https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9%2B11.1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.9_11.tar.gz - allow_failures: -# - env: RDBMS=derby -# - env: RDBMS=mariadb -# - env: RDBMS=postgresql -# - env: RDBMS=oracle -# - env: RDBMS=db2 -# - env: RDBMS=mssql - - env: JDK=11 \ No newline at end of file diff --git a/README.md b/README.md index 96de6be34f..ed603d68c3 100644 --- a/README.md +++ b/README.md @@ -148,3 +148,22 @@ You can do this from the module which you are interested in testing or from the Afterward, just pick any test from the IDE and run it as usual. Hibernate will pick the database configuration from the `hibernate.properties` file that was set up by the `setDataBase` Gradle task. + +Starting test databases locally as docker containers +------------------------------------------------------------- + +You don't have to install all databases locally to be able to test against them in case you have docker available. +The script `docker_db.sh` allows you to start a pre-configured database which can be used for testing. + +All you have to do is run the following command: + + ./docker_db.sh postgresql_9_5 + +omitting the argument will print a list of possible options. + +When the database is properly started, you can run tests with special profiles that are suffixed with `_ci` +e.g. `pgsql_ci` for PostgreSQL. By using the system property `dbHost` you can configure the IP address of your docker host. + +The command for running tests could look like the following: + + gradlew test -Pdb=pgsql_ci "-DdbHost=192.168.99.100" \ No newline at end of file diff --git a/ci/build-github.sh b/ci/build-github.sh index 281feed19c..74c0ae24de 100755 --- a/ci/build-github.sh +++ b/ci/build-github.sh @@ -4,20 +4,4 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" java -version -if [ "$RDBMS" == 'mysql' ]; then - bash $DIR/../docker_db.sh mysql_5_7 -elif [ "$RDBMS" == 'mysql8' ]; then - bash $DIR/../docker_db.sh mysql_8_0 -elif [ "$RDBMS" == 'mariadb' ]; then - bash $DIR/../docker_db.sh mariadb -elif [ "$RDBMS" == 'postgresql' ]; then - bash $DIR/../docker_db.sh postgresql_9_5 -elif [ "$RDBMS" == 'db2' ]; then - bash $DIR/../docker_db.sh db2 -elif [ "$RDBMS" == 'oracle' ]; then - bash $DIR/../docker_db.sh oracle -elif [ "$RDBMS" == 'mssql' ]; then - bash $DIR/../docker_db.sh mssql -fi - exec bash $DIR/build.sh \ No newline at end of file diff --git a/ci/build.sh b/ci/build.sh index 5a72ba2a45..30176554d9 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -8,11 +8,14 @@ elif [ "$RDBMS" == "mariadb" ]; then elif [ "$RDBMS" == "postgresql" ]; then goal="-Pdb=pgsql_ci" elif [ "$RDBMS" == "oracle" ]; then - goal="-Pdb=oracle_ci" + # I have no idea why, but these tests don't work on GH Actions + goal="-Pdb=oracle_ci -PexcludeTests=**.LockTest.testQueryTimeout*" elif [ "$RDBMS" == "db2" ]; then goal="-Pdb=db2_ci" elif [ "$RDBMS" == "mssql" ]; then goal="-Pdb=mssql_ci" +elif [ "$RDBMS" == "hana" ]; then + goal="-Pdb=hana_ci" fi -exec ./gradlew check ${goal} -Plog-test-progress=true --stacktrace \ No newline at end of file +exec ./gradlew check ${goal} -Plog-test-progress=true --stacktrace diff --git a/ci/build-travis.sh b/ci/database-start.sh similarity index 79% rename from ci/build-travis.sh rename to ci/database-start.sh index 603396112b..e603a9631b 100755 --- a/ci/build-travis.sh +++ b/ci/database-start.sh @@ -2,19 +2,13 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -java -version - if [ "$RDBMS" == 'mysql' ]; then - sudo service mysql stop bash $DIR/../docker_db.sh mysql_5_7 elif [ "$RDBMS" == 'mysql8' ]; then - sudo service mysql stop bash $DIR/../docker_db.sh mysql_8_0 elif [ "$RDBMS" == 'mariadb' ]; then - sudo service mysql stop bash $DIR/../docker_db.sh mariadb elif [ "$RDBMS" == 'postgresql' ]; then - sudo service postgres stop bash $DIR/../docker_db.sh postgresql_9_5 elif [ "$RDBMS" == 'db2' ]; then bash $DIR/../docker_db.sh db2 @@ -22,6 +16,6 @@ elif [ "$RDBMS" == 'oracle' ]; then bash $DIR/../docker_db.sh oracle elif [ "$RDBMS" == 'mssql' ]; then bash $DIR/../docker_db.sh mssql -fi - -exec bash $DIR/build.sh \ No newline at end of file +elif [ "$RDBMS" == 'hana' ]; then + bash $DIR/../docker_db.sh hana +fi \ No newline at end of file diff --git a/docker_db.sh b/docker_db.sh index 5abf61fb31..eb690d43ea 100755 --- a/docker_db.sh +++ b/docker_db.sh @@ -202,6 +202,7 @@ hana() { chmod 777 -R $temp_dir docker rm -f hana || true docker run -d --name hana -p 39013:39013 -p 39017:39017 -p 39041-39045:39041-39045 -p 1128-1129:1128-1129 -p 59013-59014:59013-59014 \ + --memory=8g \ --ulimit nofile=1048576:1048576 \ --sysctl kernel.shmmax=1073741824 \ --sysctl net.ipv4.ip_local_port_range='40000 60999' \ @@ -257,4 +258,4 @@ if [ -z ${1} ]; then echo -e "\tcockroachdb" else ${1} -fi \ No newline at end of file +fi diff --git a/gradle/databases.gradle b/gradle/databases.gradle index 4a7ca4904d..d52ac90fe0 100644 --- a/gradle/databases.gradle +++ b/gradle/databases.gradle @@ -47,7 +47,7 @@ ext { 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', // Disable prepared statement caching due to https://www.postgresql.org/message-id/CAEcMXhmmRd4-%2BNQbnjDT26XNdUoXdmntV9zdr8%3DTu8PL9aVCYg%40mail.gmail.com - 'jdbc.url' : 'jdbc:postgresql://127.0.0.1/hibernate_orm_test?preparedStatementCacheQueries=0' + 'jdbc.url' : 'jdbc:postgresql://' + dbHost + '/hibernate_orm_test?preparedStatementCacheQueries=0' ], pgsql_ci : [ 'db.dialect' : 'org.hibernate.dialect.PostgreSQLDialect', @@ -62,14 +62,14 @@ ext { 'jdbc.driver': 'com.mysql.jdbc.Driver', 'jdbc.user' : 'hibernateormtest', 'jdbc.pass' : 'hibernateormtest', - 'jdbc.url' : 'jdbc:mysql://localhost/hibernate_orm_test' + 'jdbc.url' : 'jdbc:mysql://' + dbHost + '/hibernate_orm_test' ], mysql_docker : [ 'db.dialect' : 'org.hibernate.dialect.MySQLDialect', 'jdbc.driver': 'com.mysql.jdbc.Driver', 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', - 'jdbc.url' : 'jdbc:mysql://127.0.0.1/hibernate_orm_test?useSSL=false' + 'jdbc.url' : 'jdbc:mysql://' + dbHost + '/hibernate_orm_test?useSSL=false' ], // uses docker mysql_8_0 mysql8_spatial_ci: [ @@ -84,7 +84,7 @@ ext { 'jdbc.driver': 'org.mariadb.jdbc.Driver', 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', - 'jdbc.url' : 'jdbc:mariadb://127.0.0.1/hibernate_orm_test' + 'jdbc.url' : 'jdbc:mariadb://' + dbHost + '/hibernate_orm_test' ], mariadb_ci : [ 'db.dialect' : 'org.hibernate.dialect.MariaDBDialect', @@ -113,7 +113,7 @@ ext { 'jdbc.driver': 'oracle.jdbc.OracleDriver', 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', - 'jdbc.url' : 'jdbc:oracle:thin:@localhost:1521/xe' + 'jdbc.url' : 'jdbc:oracle:thin:@' + dbHost + ':1521/xe' ], // Use ./docker_db.sh oracle_ee to start the database oracle_docker : [ @@ -142,7 +142,7 @@ ext { 'jdbc.driver': 'com.microsoft.sqlserver.jdbc.SQLServerDriver', 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', - 'jdbc.url' : 'jdbc:sqlserver://localhost;instance=SQLEXPRESS;databaseName=hibernate_orm_test' + 'jdbc.url' : 'jdbc:sqlserver://' + dbHost + ';instance=SQLEXPRESS;databaseName=hibernate_orm_test' ], mssql_ci : [ 'db.dialect' : 'org.hibernate.dialect.SQLServerDialect', @@ -163,14 +163,14 @@ ext { 'jdbc.driver': 'com.informix.jdbc.IfxDriver', 'jdbc.user' : 'informix', 'jdbc.pass' : 'in4mix', - 'jdbc.url' : 'jdbc:informix-sqli://127.0.0.1:9088/sysuser:INFORMIXSERVER=dev;user=informix;password=in4mix' + 'jdbc.url' : 'jdbc:informix-sqli://' + dbHost + ':9088/sysuser:INFORMIXSERVER=dev;user=informix;password=in4mix' ], db2 : [ 'db.dialect' : 'org.hibernate.dialect.DB2Dialect', 'jdbc.driver': 'com.ibm.db2.jcc.DB2Driver', 'jdbc.user' : 'db2inst1', 'jdbc.pass' : 'db2inst1-pwd', - 'jdbc.url' : 'jdbc:db2://127.0.0.1:50000/hibern8' + 'jdbc.url' : 'jdbc:db2://' + dbHost + ':50000/hibern8' ], db2_ci : [ 'db.dialect' : 'org.hibernate.dialect.DB2Dialect', @@ -192,7 +192,7 @@ ext { 'jdbc.user' : 'HIBERNATE_TEST', 'jdbc.pass' : 'H1bernate_test', // Disable prepared statement caching due to https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.04/en-US/78f2163887814223858e4369d18e2847.html - 'jdbc.url' : 'jdbc:sap://localhost:30015/?statementCacheSize=0' + 'jdbc.url' : 'jdbc:sap://' + dbHost + ':30015/?statementCacheSize=0' ], hana_cloud : [ 'db.dialect' : 'org.hibernate.dialect.HANACloudColumnStoreDialect', @@ -200,7 +200,7 @@ ext { 'jdbc.user' : 'HIBERNATE_TEST', 'jdbc.pass' : 'H1bernate_test', // Disable prepared statement caching due to https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.04/en-US/78f2163887814223858e4369d18e2847.html - 'jdbc.url' : 'jdbc:sap://localhost:443/?encrypt=true&validateCertificate=false&statementCacheSize=0' + 'jdbc.url' : 'jdbc:sap://' + dbHost + ':443/?encrypt=true&validateCertificate=false&statementCacheSize=0' ], hana_vlad : [ 'db.dialect' : 'org.hibernate.dialect.HANAColumnStoreDialect', @@ -208,7 +208,7 @@ ext { 'jdbc.user' : 'VLAD', 'jdbc.pass' : 'V1ad_test', // Disable prepared statement caching due to https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.04/en-US/78f2163887814223858e4369d18e2847.html - 'jdbc.url' : 'jdbc:sap://localhost:39015/?statementCacheSize=0' + 'jdbc.url' : 'jdbc:sap://' + dbHost + ':39015/?statementCacheSize=0' ], hana_docker : [ 'db.dialect' : 'org.hibernate.dialect.HANAColumnStoreDialect', @@ -218,6 +218,14 @@ ext { // Disable prepared statement caching due to https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.04/en-US/78f2163887814223858e4369d18e2847.html 'jdbc.url' : 'jdbc:sap://' + dbHost + ':39017/?statementCacheSize=0' ], + hana_ci : [ + 'db.dialect' : 'org.hibernate.dialect.HANAColumnStoreDialect', + 'jdbc.driver': 'com.sap.db.jdbc.Driver', + 'jdbc.user' : 'SYSTEM', + 'jdbc.pass' : 'H1bernate_test', + // Disable prepared statement caching due to https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.04/en-US/78f2163887814223858e4369d18e2847.html + 'jdbc.url' : 'jdbc:sap://' + dbHost + ':39017/?statementCacheSize=0' + ], hana_spatial_ci : [ 'db.dialect' : 'org.hibernate.spatial.dialect.hana.HANASpatialDialect', 'jdbc.driver': 'com.sap.db.jdbc.Driver', @@ -233,7 +241,7 @@ ext { 'jdbc.user' : 'root', 'jdbc.pass' : '', // Disable prepared statement caching due to https://www.postgresql.org/message-id/CAEcMXhmmRd4-%2BNQbnjDT26XNdUoXdmntV9zdr8%3DTu8PL9aVCYg%40mail.gmail.com - 'jdbc.url' : 'jdbc:postgresql://localhost:26257/defaultdb?sslmode=disable&preparedStatementCacheQueries=0' + 'jdbc.url' : 'jdbc:postgresql://' + dbHost + ':26257/defaultdb?sslmode=disable&preparedStatementCacheQueries=0' ], cockroachdb_spatial : [ 'db.dialect' : 'org.hibernate.spatial.dialect.cockroachdb.CockroachDB202SpatialDialect', @@ -242,7 +250,7 @@ ext { 'jdbc.user' : 'root', 'jdbc.pass' : '', // Disable prepared statement caching due to https://www.postgresql.org/message-id/CAEcMXhmmRd4-%2BNQbnjDT26XNdUoXdmntV9zdr8%3DTu8PL9aVCYg%40mail.gmail.com - 'jdbc.url' : 'jdbc:postgresql://localhost:26257/defaultdb?sslmode=disable&preparedStatementCacheQueries=0' + 'jdbc.url' : 'jdbc:postgresql://'+ dbHost +'localhost:26257/defaultdb?sslmode=disable&preparedStatementCacheQueries=0' ], firebird : [ 'db.dialect' : 'org.hibernate.dialect.FirebirdDialect', @@ -252,7 +260,7 @@ ext { // Overriding default transaction definition (5 seconds instead of infinite wait) to prevent problems in test cleanup // Expects alias 'hibernate_orm_test' in aliases.conf (FB2.5 and earlier) or databases.conf (FB3.0 and later) // Created database must either use default character set NONE, or UTF8 with page size 16384 or higher (to prevent issues with indexes due to keysize) - 'jdbc.url' : 'jdbc:firebirdsql://localhost/hibernate_orm_test?charSet=utf-8;TRANSACTION_READ_COMMITTED=read_committed,rec_version,wait,lock_timeout=5' + 'jdbc.url' : 'jdbc:firebirdsql://' + dbHost +'localhost/hibernate_orm_test?charSet=utf-8;TRANSACTION_READ_COMMITTED=read_committed,rec_version,wait,lock_timeout=5' ], ] } diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index a3db1e7f78..0db0d6a2c7 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -272,6 +272,12 @@ test { beforeTest { descriptor -> //println "Starting test: " + descriptor } + // Allow to exclude specific tests + if (project.hasProperty('excludeTests')) { + filter { + excludeTestsMatching project.property('excludeTests').toString() + } + } } diff --git a/hibernate-spatial/hibernate-spatial.gradle b/hibernate-spatial/hibernate-spatial.gradle index 4915d43296..ab0edc0fc4 100644 --- a/hibernate-spatial/hibernate-spatial.gradle +++ b/hibernate-spatial/hibernate-spatial.gradle @@ -25,6 +25,7 @@ dependencies { testCompile(libraries.junit) testCompile(project(':hibernate-testing')) + testCompile( project( path: ':hibernate-core', configuration: 'tests' ) ) testCompile([group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.8.0']) testCompile(libraries.validation) testCompile(libraries.jandex) diff --git a/hibernate-spatial/src/main/java/org/hibernate/spatial/JTSGeometryJavaTypeDescriptor.java b/hibernate-spatial/src/main/java/org/hibernate/spatial/JTSGeometryJavaTypeDescriptor.java index 0ffcde4699..535c6fc8e2 100644 --- a/hibernate-spatial/src/main/java/org/hibernate/spatial/JTSGeometryJavaTypeDescriptor.java +++ b/hibernate-spatial/src/main/java/org/hibernate/spatial/JTSGeometryJavaTypeDescriptor.java @@ -9,6 +9,7 @@ package org.hibernate.spatial; import java.util.Locale; +import org.hibernate.spatial.jts.JTSUtils; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.AbstractTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; @@ -54,6 +55,11 @@ public class JTSGeometryJavaTypeDescriptor extends AbstractTypeDescriptor X unwrap(Geometry value, Class type, WrapperOptions options) { if ( value == null ) { diff --git a/hibernate-spatial/src/main/java/org/hibernate/spatial/JTSGeometryType.java b/hibernate-spatial/src/main/java/org/hibernate/spatial/JTSGeometryType.java index 80de64fe4c..a7178039c8 100644 --- a/hibernate-spatial/src/main/java/org/hibernate/spatial/JTSGeometryType.java +++ b/hibernate-spatial/src/main/java/org/hibernate/spatial/JTSGeometryType.java @@ -48,4 +48,5 @@ public class JTSGeometryType extends AbstractSingleColumnStandardBasicType. + */ + +package org.hibernate.spatial.jts; + + +//Note that this Utility class will be available directly from +// geolatte-geom 1.9 + + +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; + +/** + * Some utility functions for working with JTS geometries + */ +public class JTSUtils { + + private JTSUtils() { + } + + /** + * Determines equality between geometries taking into + * account all coordinates, and the SRID. + *

+ * This is used e.g. for Dirty-checking of geometry values + * in Hibernate + * + * @param g1 + * @param g2 + * + * @return + */ + public static boolean equalsExact3D(Geometry g1, Geometry g2) { + if ( g1 == g2 ) { + return true; + } + if ( g1 == null || g2 == null ) { + return false; + } + if ( !g1.getGeometryType().equals( g2.getGeometryType() ) ) { + return false; + } + if ( g1.getSRID() != g2.getSRID() ) { + return false; + } + + //empty geometries of the same type are the same + if ( g1.isEmpty() && g2.isEmpty() ) { + return true; + } + + int ng1 = g1.getNumGeometries(); + int ng2 = g2.getNumGeometries(); + if ( ng1 != ng2 ) { + return false; + } + + if ( ng1 == 1 ) { + return equals3DPrimitiveGeometries( g1, g2 ); + } + + return equalComponentGeometries( g1, g2, ng1 ); + } + + private static boolean equalComponentGeometries(Geometry g1, Geometry g2, int ng1) { + for ( int gIdx = 0; gIdx < ng1; gIdx++ ) { + if ( !equalsExact3D( g1.getGeometryN( gIdx ), g2.getGeometryN( gIdx ) ) ) { + return false; + } + } + return true; + } + + public static boolean equals3D(Coordinate c1, Coordinate c2) { + return c1.x == c2.x && c1.y == c2.y && + ( ( Double.isNaN( c1.z ) && Double.isNaN( c2.z ) ) || c1.z == c2.z ) && + ( ( Double.isNaN( c1.getM() ) && Double.isNaN( c2.getM() ) ) || c1.getM() == c2.getM() ); + } + + private static boolean equalLineStringCoordinates(LineString g1, LineString g2) { + int np1 = g1.getNumPoints(); + int np2 = g2.getNumPoints(); + if ( np1 != np2 ) { + return false; + } + for ( int i = 0; i < np1; i++ ) { + if ( !equalsExact3D( g1.getPointN( i ), g2.getPointN( i ) ) ) { + return false; + } + } + return true; + } + + private static boolean equalPolygonCoordinates(Polygon g1, Polygon g2) { + int nr1 = g1.getNumInteriorRing(); + int nr2 = g2.getNumInteriorRing(); + if ( nr1 != nr2 ) { + return false; + } + for ( int i = 0; i < nr1; i++ ) { + if ( !equalLineStringCoordinates( g1.getInteriorRingN( i ), g2.getInteriorRingN( i ) ) ) { + return false; + } + } + return equalLineStringCoordinates( g1.getExteriorRing(), g2.getExteriorRing() ); + } + + private static boolean equals3DPrimitiveGeometries(Geometry g1, Geometry g2) { + //this method assumes that g1 and g2 are of the same type + assert ( g1.getClass().equals( g2.getClass() ) ); + if ( g1 instanceof Point ) { + return equals3D( g1.getCoordinate(), g2.getCoordinate() ); + } + + if ( g1 instanceof LineString ) { + return equalLineStringCoordinates( (LineString) g1, (LineString) g2 ); + } + + if ( g1 instanceof Polygon ) { + return equalPolygonCoordinates( (Polygon) g1, (Polygon) g2 ); + } + throw new IllegalStateException( "Only simple geometries should be used" ); + } +} diff --git a/hibernate-spatial/src/test/java/org/hibernate/spatial/integration/jts/hhh14523/DirtyCheckingTest.java b/hibernate-spatial/src/test/java/org/hibernate/spatial/integration/jts/hhh14523/DirtyCheckingTest.java new file mode 100644 index 0000000000..0516ecb738 --- /dev/null +++ b/hibernate-spatial/src/test/java/org/hibernate/spatial/integration/jts/hhh14523/DirtyCheckingTest.java @@ -0,0 +1,140 @@ +/* + * 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.integration.jts.hhh14523; + +import java.io.Serializable; +import java.util.List; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityManager; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Query; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; +import org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect; + +import org.hibernate.testing.RequiresDialect; +import org.hibernate.testing.TestForIssue; +import org.junit.Test; + +import org.geolatte.geom.codec.Wkt; +import org.geolatte.geom.jts.JTS; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.Point; + +import static org.junit.Assert.assertEquals; + +@TestForIssue(jiraKey = "HHH-14523") +@RequiresDialect(PostgisPG95Dialect.class) +public class DirtyCheckingTest extends BaseEntityManagerFunctionalTestCase { + + private GeometryFactory gfact = new GeometryFactory(); + + @Override + public Class[] getAnnotatedClasses() { + return new Class[] { + TestEntity.class + }; + } + + public void createtestEntity() { + Point pnt = (Point) JTS.to( Wkt.fromWkt( "POINT Z( 3.41127795 8.11062269 2.611)", Wkt.Dialect.SFA_1_2_1 ) ); + EntityManager entityManager = createEntityManager(); + TestEntity test1 = new TestEntity( "radar 5", pnt ); + + entityManager.getTransaction().begin(); + entityManager.persist( test1 ); + entityManager.getTransaction().commit(); + + entityManager.close(); + } + + // Entities are auto-discovered, so just add them anywhere on class-path + // Add your tests, using standard JUnit. + @Test + public void hhh14523() throws Exception { + + createtestEntity(); + + EntityManager entityManager = createEntityManager(); + entityManager.getTransaction().begin(); + Query query = entityManager.createQuery( "select t from TestEntity t" ); + TestEntity ent = (TestEntity) query.getResultList().get( 0 ); + Point newPnt = (Point) JTS.to( Wkt.fromWkt( "POINT Z( 3.41127795 8.11062269 8.611)", Wkt.Dialect.SFA_1_2_1 ) ); + ent.setGeom( newPnt ); + entityManager.getTransaction().commit(); + entityManager.close(); + + + entityManager = createEntityManager(); + entityManager.getTransaction().begin(); + List entities = entityManager.createQuery( "select t from TestEntity t" ).getResultList(); + TestEntity ent2 = entities.get( 0 ); + try { + assertEquals( 8.611, ent2.getGeom().getCoordinate().getZ(), 0.00001 ); + } + finally { + entityManager.getTransaction().commit(); + } + entityManager.close(); + } +} + +@Entity +@Table(name = "test") +@SequenceGenerator(name = "test_id_seq", sequenceName = "test_id_seq", allocationSize = 1) +class TestEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "test_id_seq") + @Column(name = "id") + private Long id; + + @Column(name = "uid", unique = true) + private String uid; + + @Column(name = "geom") + private Point geom; + + public TestEntity() { + } + + public TestEntity(String uid, Point geom) { + this.uid = uid; + this.geom = geom; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public Point getGeom() { + return geom; + } + + public void setGeom(Point geom) { + this.geom = geom; + } +} diff --git a/hibernate-spatial/src/test/java/org/hibernate/spatial/integration/jts/hhh14523/package-info.java b/hibernate-spatial/src/test/java/org/hibernate/spatial/integration/jts/hhh14523/package-info.java new file mode 100644 index 0000000000..939f83ef7f --- /dev/null +++ b/hibernate-spatial/src/test/java/org/hibernate/spatial/integration/jts/hhh14523/package-info.java @@ -0,0 +1,9 @@ +/* + * 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 . + */ + +//test case for bug HHH-14523 +package org.hibernate.spatial.integration.jts.hhh14523; \ No newline at end of file