From 60b2cedbaaa4ba495c68b829b444066f61ccf4b2 Mon Sep 17 00:00:00 2001 From: Vlad Mihalcea Date: Sun, 16 Apr 2023 08:09:01 +0300 Subject: [PATCH] From Hibernate 6.2, ImmutableType needs to implement BasicDomainType #609 --- .../type/DescriptorImmutableType.java | 29 ++++++++++++++++++- .../type/MutableDynamicParameterizedType.java | 3 ++ .../utils/hibernate/type/MutableType.java | 29 ++++++++++++++++++- .../type/basic/PostgreSQLCITextType.java | 7 ++--- .../interval/PostgreSQLPeriodTypeTest.java | 28 ++++++++++++++++++ .../json/OracleJsonStringPropertyTest.java | 18 +++++++++++- 6 files changed, 107 insertions(+), 7 deletions(-) diff --git a/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/DescriptorImmutableType.java b/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/DescriptorImmutableType.java index e466abed6..93857f651 100644 --- a/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/DescriptorImmutableType.java +++ b/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/DescriptorImmutableType.java @@ -3,12 +3,14 @@ import io.hypersistence.utils.hibernate.type.util.Configuration; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.metamodel.model.domain.BasicDomainType; import org.hibernate.query.BindableType; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.usertype.UserType; +import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -18,7 +20,7 @@ * * @author Vlad Mihalcea */ -public abstract class DescriptorImmutableType> extends ImmutableType implements BindableType, SqmExpressible { +public abstract class DescriptorImmutableType> extends ImmutableType implements BindableType, SqmExpressible, BasicDomainType { private final JDBC jdbcTypeDescriptor; private final JAVA javaTypeDescriptor; @@ -70,4 +72,29 @@ public Class getBindableJavaType() { public JavaType getExpressibleJavaType() { return javaTypeDescriptor; } + + @Override + public Class getJavaType() { + return returnedClass(); + } + + @Override + public boolean canDoExtraction() { + return true; + } + + @Override + public JdbcType getJdbcType() { + return jdbcTypeDescriptor; + } + + @Override + public T extract(CallableStatement callableStatement, int position, SharedSessionContractImplementor session) throws SQLException { + return jdbcTypeDescriptor.getExtractor(javaTypeDescriptor).extract(callableStatement, position, session); + } + + @Override + public T extract(CallableStatement callableStatement, String position, SharedSessionContractImplementor session) throws SQLException { + return jdbcTypeDescriptor.getExtractor(javaTypeDescriptor).extract(callableStatement, position, session); + } } diff --git a/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/MutableDynamicParameterizedType.java b/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/MutableDynamicParameterizedType.java index 7f8a723d9..b026d5e93 100644 --- a/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/MutableDynamicParameterizedType.java +++ b/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/MutableDynamicParameterizedType.java @@ -1,11 +1,14 @@ package io.hypersistence.utils.hibernate.type; import io.hypersistence.utils.hibernate.type.util.Configuration; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.usertype.DynamicParameterizedType; import org.hibernate.usertype.ParameterizedType; +import java.sql.CallableStatement; +import java.sql.SQLException; import java.util.Properties; /** diff --git a/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/MutableType.java b/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/MutableType.java index 7304d43cd..cb1efd4e1 100644 --- a/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/MutableType.java +++ b/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/MutableType.java @@ -9,6 +9,7 @@ import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.MappingType; +import org.hibernate.metamodel.model.domain.BasicDomainType; import org.hibernate.query.BindableType; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.type.descriptor.java.JavaType; @@ -17,6 +18,7 @@ import org.hibernate.usertype.UserType; import java.io.Serializable; +import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -26,7 +28,7 @@ * * @author Vlad Mihalcea */ -public abstract class MutableType> implements UserType, BindableType, SqmExpressible, BasicValuedMapping { +public abstract class MutableType> implements UserType, BindableType, SqmExpressible, BasicValuedMapping, BasicDomainType { private final Class clazz; @@ -175,4 +177,29 @@ public int forEachJdbcType(int offset, IndexedConsumer action) { action.accept(offset, jdbcMapping); return getJdbcTypeCount(); } + + @Override + public Class getJavaType() { + return returnedClass(); + } + + @Override + public boolean canDoExtraction() { + return true; + } + + @Override + public JdbcType getJdbcType() { + return jdbcTypeDescriptor; + } + + @Override + public T extract(CallableStatement callableStatement, int position, SharedSessionContractImplementor session) throws SQLException { + return jdbcTypeDescriptor.getExtractor(javaTypeDescriptor).extract(callableStatement, position, session); + } + + @Override + public T extract(CallableStatement callableStatement, String position, SharedSessionContractImplementor session) throws SQLException { + return jdbcTypeDescriptor.getExtractor(javaTypeDescriptor).extract(callableStatement, position, session); + } } \ No newline at end of file diff --git a/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/basic/PostgreSQLCITextType.java b/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/basic/PostgreSQLCITextType.java index 7b717ce65..8af7b4884 100644 --- a/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/basic/PostgreSQLCITextType.java +++ b/hypersistence-utils-hibernate-62/src/main/java/io/hypersistence/utils/hibernate/type/basic/PostgreSQLCITextType.java @@ -4,11 +4,10 @@ import io.hypersistence.utils.hibernate.type.util.Configuration; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.type.descriptor.jdbc.JdbcType; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; +import java.io.Serializable; +import java.sql.*; /** * Maps a {@link String} object type to a PostgreSQL citext diff --git a/hypersistence-utils-hibernate-62/src/test/java/io/hypersistence/utils/hibernate/type/interval/PostgreSQLPeriodTypeTest.java b/hypersistence-utils-hibernate-62/src/test/java/io/hypersistence/utils/hibernate/type/interval/PostgreSQLPeriodTypeTest.java index 13dd6b27d..707882cd3 100644 --- a/hypersistence-utils-hibernate-62/src/test/java/io/hypersistence/utils/hibernate/type/interval/PostgreSQLPeriodTypeTest.java +++ b/hypersistence-utils-hibernate-62/src/test/java/io/hypersistence/utils/hibernate/type/interval/PostgreSQLPeriodTypeTest.java @@ -1,13 +1,19 @@ package io.hypersistence.utils.hibernate.type.interval; +import io.hypersistence.utils.hibernate.type.array.EnumArrayType; +import io.hypersistence.utils.hibernate.type.array.ListArrayTypeTest; import io.hypersistence.utils.hibernate.type.model.BaseEntity; import io.hypersistence.utils.hibernate.util.AbstractPostgreSQLIntegrationTest; import jakarta.persistence.Column; import jakarta.persistence.Entity; import org.hibernate.annotations.Type; +import org.hibernate.jpa.boot.spi.TypeContributorList; +import org.hibernate.query.NativeQuery; import org.junit.Test; import java.time.Period; +import java.util.Collections; +import java.util.Properties; import static org.junit.Assert.assertEquals; @@ -23,6 +29,16 @@ protected Class[] entities() { return new Class[]{WorkShift.class}; } + @Override + protected void additionalProperties(Properties properties) { + properties.put("hibernate.type_contributors", + (TypeContributorList) () -> Collections.singletonList( + (typeContributions, serviceRegistry) -> { + typeContributions.contributeType(PostgreSQLPeriodType.INSTANCE); + } + )); + } + @Test public void test() { Period duration = Period.of(1, 2, 3); @@ -39,6 +55,18 @@ public void test() { WorkShift result = entityManager.find(WorkShift.class, 1L); assertEquals(duration, result.getDuration()); }); + + doInJPA(entityManager -> { + Object result = entityManager.createNativeQuery( + "select duration " + + "from WorkShift " + + "where id = :id") + .setParameter("id", 1L) + .unwrap(NativeQuery.class) + .addScalar("duration", Period.class) + .getSingleResult(); + assertEquals(duration, result); + }); } @Entity(name = "WorkShift") diff --git a/hypersistence-utils-hibernate-62/src/test/java/io/hypersistence/utils/hibernate/type/json/OracleJsonStringPropertyTest.java b/hypersistence-utils-hibernate-62/src/test/java/io/hypersistence/utils/hibernate/type/json/OracleJsonStringPropertyTest.java index 499e32384..3f89dbe96 100644 --- a/hypersistence-utils-hibernate-62/src/test/java/io/hypersistence/utils/hibernate/type/json/OracleJsonStringPropertyTest.java +++ b/hypersistence-utils-hibernate-62/src/test/java/io/hypersistence/utils/hibernate/type/json/OracleJsonStringPropertyTest.java @@ -27,7 +27,7 @@ public class OracleJsonStringPropertyTest extends AbstractOracleIntegrationTest @Override protected Class[] entities() { return new Class[]{ - Book.class + Book.class }; } @@ -97,6 +97,22 @@ public void test() { assertEquals("High-Performance Java Persistence", properties.get("title").asText()); }); + + doInJPA(entityManager -> { + JsonNode properties = (JsonNode) entityManager + .createNativeQuery( + "SELECT " + + " properties AS properties " + + "FROM book " + + "WHERE " + + " isbn = :isbn") + .setParameter("isbn", "978-9730228236") + .unwrap(NativeQuery.class) + .addScalar("properties", JsonStringType.INSTANCE) + .getSingleResult(); + + assertEquals("High-Performance Java Persistence", properties.get("title").asText()); + }); } @Test