From b166e684e1e5a7c8062d63e938a2a2deb0e9729b Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Tue, 6 Apr 2021 14:24:13 +0200 Subject: [PATCH 1/2] Skip certain LockTests for Oracle on GH Actions which don't work there --- .github/workflows/contributor-build.yml | 13 +++++- .travis.yml | 56 ----------------------- README.md | 19 ++++++++ ci/build-github.sh | 16 ------- ci/build.sh | 7 ++- ci/{build-travis.sh => database-start.sh} | 12 ++--- docker_db.sh | 3 +- gradle/databases.gradle | 34 ++++++++------ hibernate-core/hibernate-core.gradle | 6 +++ 9 files changed, 68 insertions(+), 98 deletions(-) delete mode 100644 .travis.yml rename ci/{build-travis.sh => database-start.sh} (79%) 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 005d039071..8f5a40840b 100644 --- a/README.md +++ b/README.md @@ -146,3 +146,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 eee8c47bd5..4f0cd16494 100755 --- a/docker_db.sh +++ b/docker_db.sh @@ -197,6 +197,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' \ @@ -251,4 +252,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 8e62ba2fee..cf54fda5dd 100644 --- a/gradle/databases.gradle +++ b/gradle/databases.gradle @@ -45,7 +45,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.PostgreSQL95Dialect', @@ -60,14 +60,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.MySQL57Dialect', '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: [ @@ -82,7 +82,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.MariaDB103Dialect', @@ -111,7 +111,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 : [ @@ -140,7 +140,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.SQLServer2012Dialect', @@ -161,14 +161,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', @@ -190,7 +190,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', @@ -198,7 +198,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', @@ -206,7 +206,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', @@ -216,6 +216,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', @@ -231,7 +239,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', @@ -240,7 +248,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' ] ] } diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index bfedf123cd..f4ae9c5270 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -251,6 +251,12 @@ test { beforeTest { descriptor -> //println "Starting test: " + descriptor } + // Allow to exclude specific tests + if (project.hasProperty('excludeTests')) { + filter { + excludeTestsMatching project.property('excludeTests').toString() + } + } } //Create the task that runs the integration tests found from the From e76241a3091078713dd4b57de085f5fadce5e0db Mon Sep 17 00:00:00 2001 From: Karel Maesen Date: Wed, 31 Mar 2021 21:30:35 +0200 Subject: [PATCH 2/2] HHH-14523 Fix for dirty-checking bug --- hibernate-spatial/hibernate-spatial.gradle | 1 + .../JTSGeometryJavaTypeDescriptor.java | 6 + .../hibernate/spatial/JTSGeometryType.java | 1 + .../org/hibernate/spatial/jts/JTSUtils.java | 132 +++++++++++++++++ .../jts/hhh14523/DirtyCheckingTest.java | 140 ++++++++++++++++++ .../jts/hhh14523/package-info.java | 9 ++ 6 files changed, 289 insertions(+) create mode 100644 hibernate-spatial/src/main/java/org/hibernate/spatial/jts/JTSUtils.java create mode 100644 hibernate-spatial/src/test/java/org/hibernate/spatial/integration/jts/hhh14523/DirtyCheckingTest.java create mode 100644 hibernate-spatial/src/test/java/org/hibernate/spatial/integration/jts/hhh14523/package-info.java 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 8136c455b1..4eaedf43e0 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