Repository: quarkusio/quarkus
Issue: Using duration with hibernate and postgres interval leads to error in native mode

### Describe the bug

Using hibernate with duration, which now with hibernate 6.2 uses the postgres interval type leads to an error due to `PGInterval` not correctly registered for reflection:

```
Caused by: org.postgresql.util.PSQLException: Failed to create object for: interval.
	at org.postgresql.jdbc.PgConnection.getObject(PgConnection.java:760)
	at org.postgresql.jdbc.PgResultSet.getObject(PgResultSet.java:3020)
	at io.agroal.pool.wrapper.ResultSetWrapper.getObject(ResultSetWrapper.java:472)
	at io.hypersistence.utils.hibernate.type.interval.PostgreSQLIntervalType.get(PostgreSQLIntervalType.java:40)
	at io.hypersistence.utils.hibernate.type.interval.PostgreSQLIntervalType.get(PostgreSQLIntervalType.java:24)
	at io.hypersistence.utils.hibernate.type.ImmutableType.nullSafeGet(ImmutableType.java:97)
	at org.hibernate.type.internal.UserTypeSqlTypeAdapter$ValueExtractorImpl.extract(UserTypeSqlTypeAdapter.java:110)
	at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.readCurrentRowValues(JdbcValuesResultSetImpl.java:262)
	... 87 more
Caused by: java.lang.NoSuchMethodException: org.postgresql.util.PGInterval.<init>()
	at java.base@17.0.7/java.lang.Class.getConstructor0(DynamicHub.java:3585)
	at java.base@17.0.7/java.lang.Class.getDeclaredConstructor(DynamicHub.java:2754)
	at org.postgresql.jdbc.PgConnection.getObject(PgConnection.java:739)
	... 94 more
```


### Expected behavior

This probably should work out of the box as it is now in the standard hibernate implementation.

### Actual behavior

_No response_

### How to Reproduce?

_No response_

### Output of `uname -a` or `ver`

_No response_

### Output of `java -version`

_No response_

### GraalVM version (if different from Java)

Mandrel 22.3.2.1

### Quarkus version or git rev

3.0.2.Final

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

gradlew 8.1.1

### Additional information

_No response_

Changed files:
integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/Person.java
integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/JPAFunctionalityTestEndpoint.java
extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/PostgreSQLJDBCReflections.java

diff --git a/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/PostgreSQLJDBCReflections.java b/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/PostgreSQLJDBCReflections.java
index e0e455bb140..6b351c42071 100644
--- a/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/PostgreSQLJDBCReflections.java
+++ b/extensions/jdbc/jdbc-postgresql/deployment/src/main/java/io/quarkus/jdbc/postgresql/deployment/PostgreSQLJDBCReflections.java
@@ -20,6 +20,27 @@ void build(BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
         final String driverName = "org.postgresql.Driver";
         reflectiveClass.produce(ReflectiveClassBuildItem.builder(driverName).build());
 
+        // We want to register these postgresql "object" types since they are used by a driver to build result set elements
+        // and reflection is used to create their instances. While ORM might only use a `PGInterval` if a @JdbcType(PostgreSQLIntervalSecondJdbcType.class)
+        // is applied to a Duration property, we still register other types as users might create their own JdbcTypes that
+        // would rely on some subtype of a PGobject:
+        final String[] pgObjectClasses = new String[] {
+                "org.postgresql.util.PGobject",
+                "org.postgresql.util.PGInterval",
+                "org.postgresql.util.PGmoney",
+                "org.postgresql.geometric.PGbox",
+                "org.postgresql.geometric.PGcircle",
+                "org.postgresql.geometric.PGline",
+                "org.postgresql.geometric.PGlseg",
+                "org.postgresql.geometric.PGpath",
+                "org.postgresql.geometric.PGpoint",
+                "org.postgresql.geometric.PGpolygon",
+                // One more subtype of the PGobject, it doesn't look like that this one will be instantiated through reflection,
+                // so let's not include it:
+                // "org.postgresql.jdbc.PgResultSet.NullObject"
+        };
+        reflectiveClass.produce(ReflectiveClassBuildItem.builder(pgObjectClasses).build());
+
         // Needed when quarkus.datasource.jdbc.transactions=xa for the setting of the username and password
         reflectiveClass.produce(ReflectiveClassBuildItem.builder("org.postgresql.ds.common.BaseDataSource").constructors(false)
                 .methods().build());
diff --git a/integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/JPAFunctionalityTestEndpoint.java b/integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/JPAFunctionalityTestEndpoint.java
index 6b2af30915a..0bc9b7d02b6 100644
--- a/integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/JPAFunctionalityTestEndpoint.java
+++ b/integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/JPAFunctionalityTestEndpoint.java
@@ -2,6 +2,7 @@
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.time.Duration;
 import java.util.List;
 import java.util.UUID;
 
@@ -135,6 +136,7 @@ private static void persistNewPerson(EntityManager entityManager, String name) {
         person.setName(name);
         person.setStatus(Status.LIVING);
         person.setAddress(new SequencedAddress("Street " + randomName()));
+        person.setLatestLunchBreakDuration(Duration.ofMinutes(30));
         entityManager.persist(person);
     }
 
diff --git a/integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/Person.java b/integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/Person.java
index 0393fd951f1..f8c82d346ee 100644
--- a/integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/Person.java
+++ b/integration-tests/jpa-postgresql/src/main/java/io/quarkus/it/jpa/postgresql/Person.java
@@ -1,6 +1,9 @@
 package io.quarkus.it.jpa.postgresql;
 
+import java.time.Duration;
+
 import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
 import jakarta.persistence.Entity;
 import jakarta.persistence.FetchType;
 import jakarta.persistence.GeneratedValue;
@@ -10,6 +13,9 @@
 import jakarta.persistence.NamedQuery;
 import jakarta.persistence.Table;
 
+import org.hibernate.annotations.JdbcType;
+import org.hibernate.dialect.PostgreSQLIntervalSecondJdbcType;
+
 @Entity
 @Table(schema = "myschema")
 @NamedQuery(name = "get_person_by_name", query = "select p from Person p where name = :name")
@@ -19,6 +25,7 @@ public class Person {
     private String name;
     private SequencedAddress address;
     private Status status;
+    private Duration latestLunchBreakDuration = Duration.ZERO;
 
     public Person() {
     }
@@ -64,8 +71,27 @@ public void setStatus(Status status) {
         this.status = status;
     }
 
+    /**
+     * Need to explicitly set the scale (and the precision so that the scale will actually be read from the annotation).
+     * Postgresql would only allow maximum scale of 6 for a `interval second`.
+     *
+     * @see org.hibernate.type.descriptor.sql.internal.Scale6IntervalSecondDdlType
+     */
+    @Column(precision = 5, scale = 5)
+    //NOTE: while https://hibernate.atlassian.net/browse/HHH-16591 is open we cannot replace the currently used @JdbcType annotation
+    // with a @JdbcTypeCode( INTERVAL_SECOND )
+    @JdbcType(PostgreSQLIntervalSecondJdbcType.class)
+    public Duration getLatestLunchBreakDuration() {
+        return latestLunchBreakDuration;
+    }
+
+    public void setLatestLunchBreakDuration(Duration duration) {
+        this.latestLunchBreakDuration = duration;
+    }
+
     public void describeFully(StringBuilder sb) {
         sb.append("Person with id=").append(id).append(", name='").append(name).append("', status='").append(status)
+                .append("', latestLunchBreakDuration='").append(latestLunchBreakDuration)
                 .append("', address { ");
         getAddress().describeFully(sb);
         sb.append(" }");