From dc6c10f27c050bdaaa25ff06f548bd53d309d15b Mon Sep 17 00:00:00 2001 From: Eduardo Nunes Date: Mon, 6 Jan 2025 13:53:15 -0300 Subject: [PATCH 1/2] test case reproducer --- orm/docker-compose.yml | 22 +++++++++ orm/hibernate-orm-6/pom.xml | 27 +++++++++-- .../org/hibernate/bugs/JPAUnitTestCase.java | 36 +++++++++++++-- .../bugs/QuarkusLikeORMUnitTestCase.java | 4 +- .../org/hibernate/bugs/model/Location.java | 46 +++++++++++++++++++ .../java/org/hibernate/bugs/model/Point.java | 26 +++++++++++ .../test/resources/META-INF/persistence.xml | 9 ++-- 7 files changed, 157 insertions(+), 13 deletions(-) create mode 100644 orm/docker-compose.yml create mode 100644 orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Location.java create mode 100644 orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Point.java diff --git a/orm/docker-compose.yml b/orm/docker-compose.yml new file mode 100644 index 00000000..3c20b8a9 --- /dev/null +++ b/orm/docker-compose.yml @@ -0,0 +1,22 @@ +services: + postgres: + container_name: postgres + hostname: postgres + image: postgis/postgis:16-3.5 + environment: + POSTGRES_PASSWORD: 'password' + POSTGRES_USER: 'postgres' + POSTGRES_DB: 'database' + ports: + - "5432:5432" + volumes: + - postgres:/var/lib/postgresql/data + restart: always + networks: + - nw +networks: + nw: + driver: bridge + +volumes: + postgres: \ No newline at end of file diff --git a/orm/hibernate-orm-6/pom.xml b/orm/hibernate-orm-6/pom.xml index 98b8b74c..0c8e944d 100644 --- a/orm/hibernate-orm-6/pom.xml +++ b/orm/hibernate-orm-6/pom.xml @@ -38,12 +38,21 @@ org.hibernate.orm hibernate-core + + + + + - com.h2database - h2 - ${version.com.h2database} + net.postgis + postgis-jdbc + 2024.1.0 + + + org.postgresql + postgresql + 42.7.4 - org.hibernate.orm hibernate-testing @@ -70,6 +79,16 @@ ${version.org.assertj.assertj-core} test + + org.hibernate.orm + hibernate-spatial + 6.6.3.Final + + + com.fasterxml.jackson.core + jackson-databind + 2.18.2 + diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java index 3734df49..09db3fdb 100644 --- a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java @@ -1,5 +1,8 @@ package org.hibernate.bugs; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.hibernate.bugs.model.Point; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -8,6 +11,8 @@ import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; +import java.util.List; + /** * This template demonstrates how to develop a test case for Hibernate ORM, using the Java Persistence API. */ @@ -28,11 +33,36 @@ void destroy() { // Entities are auto-discovered, so just add them anywhere on class-path // Add your tests, using standard JUnit. @Test - void hhh123Test() throws Exception { + void hhh18956Test() throws Exception { EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); - // Do stuff... + + final String query = createNativeQuery(); + entityManager.createNativeQuery(query).executeUpdate(); entityManager.getTransaction().commit(); - entityManager.close(); + + entityManager.close();; + } + + private String createNativeQuery() throws JsonProcessingException { + final String nativeQuery = "INSERT INTO location (point) " + + "VALUES (%s) " + + "ON CONFLICT DO NOTHING;"; + + final String dollarQuotedGeoJsonValue = makeDollarQuotedValue(); + return String.format(nativeQuery, dollarQuotedGeoJsonValue); } + + private String makeDollarQuotedValue() throws JsonProcessingException { + final String dollarQuote = "$asdas$"; + final String postgisWrapper = "ST_SetSRID(ST_GeomFromGeoJSON(%s%s%s), 4326)"; + return String.format(postgisWrapper, dollarQuote, makePoint(), dollarQuote); + } + + private String makePoint() throws JsonProcessingException { + Point point = new Point(List.of(30.5, 50.4)); + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(point); + } + } diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/QuarkusLikeORMUnitTestCase.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/QuarkusLikeORMUnitTestCase.java index f96bffd4..7bc1f0b0 100644 --- a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/QuarkusLikeORMUnitTestCase.java +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/QuarkusLikeORMUnitTestCase.java @@ -17,7 +17,7 @@ import org.hibernate.cfg.AvailableSettings; -import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced; +//import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced; import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.SessionFactory; @@ -60,7 +60,7 @@ } ) @SessionFactory -@BytecodeEnhanced +//@BytecodeEnhanced class QuarkusLikeORMUnitTestCase { // Add your tests, using standard JUnit. diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Location.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Location.java new file mode 100644 index 00000000..1b117b7d --- /dev/null +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Location.java @@ -0,0 +1,46 @@ +package org.hibernate.bugs.model; + +import jakarta.persistence.*; +import org.locationtech.jts.geom.Point; + +@Entity +public class Location { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private Point point; + + public Location() { + } + + public Location(Long id, Point point) { + this.id = id; + this.point = point; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Point getPoint() { + return point; + } + + public void setPoint(Point point) { + this.point = point; + } + + @Override + public String toString() { + return "Location{" + + "id=" + id + + ", point=" + point + + '}'; + } +} diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Point.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Point.java new file mode 100644 index 00000000..9970c0c2 --- /dev/null +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Point.java @@ -0,0 +1,26 @@ +package org.hibernate.bugs.model; + +import java.util.List; + +public class Point { + + private String type; + private List coordinates; + + public Point() { + type = "Point"; + } + + public Point(List coordinates) { + type = "Point"; + this.coordinates = coordinates; + } + + public String getType() { + return type; + } + + public List getCoordinates() { + return coordinates; + } +} diff --git a/orm/hibernate-orm-6/src/test/resources/META-INF/persistence.xml b/orm/hibernate-orm-6/src/test/resources/META-INF/persistence.xml index 3c18b748..e6a4ef2a 100644 --- a/orm/hibernate-orm-6/src/test/resources/META-INF/persistence.xml +++ b/orm/hibernate-orm-6/src/test/resources/META-INF/persistence.xml @@ -13,10 +13,11 @@ - - - - + + + + + From c4a6fee48ef32b2098a0e44149175d01d576246b Mon Sep 17 00:00:00 2001 From: Eduardo Nunes Date: Mon, 6 Jan 2025 14:16:47 -0300 Subject: [PATCH 2/2] reproducer --- .../org/hibernate/bugs/JPAUnitTestCase.java | 32 ++++++++++++++----- .../org/hibernate/bugs/model/Location.java | 1 - 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java index 09db3fdb..e10946e6 100644 --- a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.hibernate.bugs.model.Location; import org.hibernate.bugs.model.Point; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -13,11 +15,17 @@ import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; + /** * This template demonstrates how to develop a test case for Hibernate ORM, using the Java Persistence API. */ class JPAUnitTestCase { + private static final Long LOCATION_ID = 123412L; + private static final String DOLLAR_QUOTE = "$asdas$"; + + private EntityManagerFactory entityManagerFactory; @BeforeEach @@ -39,24 +47,32 @@ void hhh18956Test() throws Exception { final String query = createNativeQuery(); entityManager.createNativeQuery(query).executeUpdate(); - entityManager.getTransaction().commit(); + final Location location = entityManager.find(Location.class, LOCATION_ID); + Assertions.assertEquals(LOCATION_ID, location.getId()); + Assertions.assertNotNull(location.getPoint()); + + entityManager.getTransaction().commit(); entityManager.close();; } private String createNativeQuery() throws JsonProcessingException { - final String nativeQuery = "INSERT INTO location (point) " + - "VALUES (%s) " + + final String nativeQuery = "INSERT INTO location (id, point) " + + "VALUES (%s, %s) " + "ON CONFLICT DO NOTHING;"; - final String dollarQuotedGeoJsonValue = makeDollarQuotedValue(); - return String.format(nativeQuery, dollarQuotedGeoJsonValue); + final String dollarQuotedGeoJsonValue = makeDollarQuotedPoint(); + final String dollarQuotedId = makeDollarQuotedId(); + return String.format(nativeQuery, dollarQuotedId, dollarQuotedGeoJsonValue); } - private String makeDollarQuotedValue() throws JsonProcessingException { - final String dollarQuote = "$asdas$"; + private String makeDollarQuotedPoint() throws JsonProcessingException { final String postgisWrapper = "ST_SetSRID(ST_GeomFromGeoJSON(%s%s%s), 4326)"; - return String.format(postgisWrapper, dollarQuote, makePoint(), dollarQuote); + return String.format(postgisWrapper, DOLLAR_QUOTE, makePoint(), DOLLAR_QUOTE); + } + + private String makeDollarQuotedId() { + return DOLLAR_QUOTE.concat(String.valueOf(LOCATION_ID)).concat(DOLLAR_QUOTE); } private String makePoint() throws JsonProcessingException { diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Location.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Location.java index 1b117b7d..4d4f4506 100644 --- a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Location.java +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/model/Location.java @@ -7,7 +7,6 @@ public class Location { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Point point;