diff --git a/hibernate-core/src/main/java/org/hibernate/Interceptor.java b/hibernate-core/src/main/java/org/hibernate/Interceptor.java
index dad428c2dfac..7f266d9d7053 100644
--- a/hibernate-core/src/main/java/org/hibernate/Interceptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/Interceptor.java
@@ -47,6 +47,10 @@
  *          However, JPA callbacks do not provide the ability to access the previous
  *          value of an updated property in a {@code @PreUpdate} callback, and do not
  *          provide a well-defined way to intercept changes to collections.
+ *          
+ *          Note that this API exposes the interface {@link Type}, which in modern
+ *          versions of Hibernate is considered an SPI. This is unfortunate, and might
+ *          change in the future, but is bearable for now.
  *
  * @see SessionBuilder#interceptor(Interceptor)
  * @see SharedSessionBuilder#interceptor()
diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcCallImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcCallImpl.java
index f4bec9f30cbe..265a55166593 100644
--- a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcCallImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcCallImpl.java
@@ -5,7 +5,6 @@
 package org.hibernate.sql.exec.internal;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -23,6 +22,10 @@
 import org.hibernate.sql.exec.spi.JdbcParameterBindings;
 import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
 
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.unmodifiableList;
+
 /**
  * Models the actual call, allowing iterative building of the parts.
  *
@@ -42,17 +45,17 @@ public JdbcCallImpl(Builder builder) {
 				builder.callableName,
 				builder.functionReturn,
 				builder.parameterRegistrations == null
-						? Collections.emptyList()
-						: Collections.unmodifiableList( builder.parameterRegistrations ),
+						? emptyList()
+						: unmodifiableList( builder.parameterRegistrations ),
 				builder.parameterBinders == null
-						? Collections.emptyList()
-						: Collections.unmodifiableList( builder.parameterBinders ),
+						? emptyList()
+						: unmodifiableList( builder.parameterBinders ),
 				builder.parameterExtractors == null
-						? Collections.emptyList()
-						: Collections.unmodifiableList( builder.parameterExtractors ),
+						? emptyList()
+						: unmodifiableList( builder.parameterExtractors ),
 				builder.refCursorExtractors == null
-						? Collections.emptyList()
-						: Collections.unmodifiableList( builder.refCursorExtractors )
+						? emptyList()
+						: unmodifiableList( builder.refCursorExtractors )
 		);
 	}
 
@@ -99,12 +102,12 @@ public JdbcCallFunctionReturn getFunctionReturn() {
 
 	@Override
 	public List getParameterRegistrations() {
-		return parameterRegistrations == null ? Collections.emptyList() : parameterRegistrations;
+		return parameterRegistrations == null ? emptyList() : parameterRegistrations;
 	}
 
 	@Override
 	public List getParameterBinders() {
-		return parameterBinders == null ? Collections.emptyList() : parameterBinders;
+		return parameterBinders == null ? emptyList() : parameterBinders;
 	}
 
 	@Override
@@ -119,7 +122,7 @@ public boolean dependsOnParameterBindings() {
 
 	@Override
 	public Map getAppliedParameters() {
-		return Collections.emptyMap();
+		return emptyMap();
 	}
 
 	@Override
@@ -130,12 +133,12 @@ public boolean isCompatibleWith(
 
 	@Override
 	public List getParameterExtractors() {
-		return parameterExtractors == null ? Collections.emptyList() : parameterExtractors;
+		return parameterExtractors == null ? emptyList() : parameterExtractors;
 	}
 
 	@Override
 	public List getCallRefCursorExtractors() {
-		return refCursorExtractors == null ? Collections.emptyList() : refCursorExtractors;
+		return refCursorExtractors == null ? emptyList() : refCursorExtractors;
 	}
 
 	@Override
diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcCallRefCursorExtractorImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcCallRefCursorExtractorImpl.java
index f855e02db08f..8fe5a350f358 100644
--- a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcCallRefCursorExtractorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcCallRefCursorExtractorImpl.java
@@ -30,10 +30,10 @@ public JdbcCallRefCursorExtractorImpl(
 	public ResultSet extractResultSet(
 			CallableStatement callableStatement,
 			SharedSessionContractImplementor session) {
-		final boolean supportsNamedParameters = session.getJdbcServices()
-				.getJdbcEnvironment()
-				.getExtractedDatabaseMetaData()
-				.supportsNamedParameters();
+//		final boolean supportsNamedParameters = session.getJdbcServices()
+//				.getJdbcEnvironment()
+//				.getExtractedDatabaseMetaData()
+//				.supportsNamedParameters();
 		return session.getFactory()
 				.getServiceRegistry()
 				.requireService( RefCursorSupport.class )
diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingsImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingsImpl.java
index 121735909106..93560dec8d6d 100644
--- a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingsImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingsImpl.java
@@ -5,13 +5,11 @@
 package org.hibernate.sql.exec.internal;
 
 import java.util.Collection;
-import java.util.Collections;
 import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.function.BiConsumer;
 
-import org.hibernate.dialect.Dialect;
 import org.hibernate.engine.spi.SessionFactoryImplementor;
 import org.hibernate.metamodel.mapping.BasicValuedMapping;
 import org.hibernate.metamodel.mapping.JdbcMapping;
@@ -19,7 +17,6 @@
 import org.hibernate.query.spi.QueryParameterBinding;
 import org.hibernate.query.spi.QueryParameterBindings;
 import org.hibernate.query.spi.QueryParameterImplementor;
-import org.hibernate.query.sql.internal.NativeQueryImpl;
 import org.hibernate.query.sql.spi.ParameterOccurrence;
 import org.hibernate.sql.ast.tree.expression.JdbcParameter;
 import org.hibernate.sql.exec.spi.JdbcParameterBinder;
@@ -28,6 +25,9 @@
 import org.hibernate.type.BasicTypeReference;
 import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
 
+import static java.util.Collections.emptyList;
+import static org.hibernate.query.sql.internal.NativeQueryImpl.determineBindValueMaxCount;
+
 /**
  * Standard implementation of JdbcParameterBindings
  *
@@ -50,42 +50,22 @@ public JdbcParameterBindingsImpl(
 		if ( !parameterOccurrences.isEmpty() ) {
 			bindingMap = new IdentityHashMap<>( parameterOccurrences.size() );
 
-			final Dialect dialect = factory.getJdbcServices().getDialect();
 			final boolean paddingEnabled = factory.getSessionFactoryOptions().inClauseParameterPaddingEnabled();
-			final int inExprLimit = dialect.getParameterCountLimit();
+			final int inExprLimit = factory.getJdbcServices().getDialect().getParameterCountLimit();
 
 			for ( ParameterOccurrence occurrence : parameterOccurrences ) {
 				final QueryParameterImplementor> param = occurrence.parameter();
 				final QueryParameterBinding> binding = queryParameterBindings.getBinding( param );
 
-				final JdbcMapping jdbcMapping;
-
-				final BindableType> type = determineParamType( param, binding );
-				if ( type == null ) {
-					jdbcMapping = factory.getTypeConfiguration().getBasicTypeForJavaType( Object.class );
-				}
-				else if ( type instanceof BasicTypeReference> basicTypeReference ) {
-					jdbcMapping =
-							factory.getTypeConfiguration().getBasicTypeRegistry()
-									.resolve( basicTypeReference );
-				}
-				else if ( type instanceof BasicValuedMapping basicValuedMapping ) {
-					jdbcMapping = basicValuedMapping.getJdbcMapping();
-				}
-				else {
-					throw new IllegalArgumentException( "Could not resolve NativeQuery parameter type : `" + param + "`");
-				}
+				final JdbcMapping jdbcMapping = jdbcMapping( factory, param, binding );
 
 				final BasicValueConverter valueConverter = jdbcMapping == null ? null : jdbcMapping.getValueConverter();
 
 				if ( binding.isMultiValued() ) {
 					final Collection> bindValues = binding.getBindValues();
 					final int bindValueCount = bindValues.size();
-					final int bindValueMaxCount = NativeQueryImpl.determineBindValueMaxCount(
-							paddingEnabled,
-							inExprLimit,
-							bindValueCount
-					);
+					final int bindValueMaxCount =
+							determineBindValueMaxCount( paddingEnabled, inExprLimit, bindValueCount );
 					Object lastBindValue = null;
 					if ( valueConverter != null ) {
 						for ( Object bindValue : bindValues ) {
@@ -119,31 +99,38 @@ else if ( type instanceof BasicValuedMapping basicValuedMapping ) {
 					}
 				}
 				else {
-					final Object bindValue;
-					if ( valueConverter != null && binding.getBindValue() != null ) {
-						bindValue = valueConverter.toRelationalValue( binding.getBindValue() );
-					}
-					else {
-						bindValue = binding.getBindValue();
-					}
-
+					final Object bindValue =
+							valueConverter != null && binding.getBindValue() != null
+									? valueConverter.toRelationalValue( binding.getBindValue() )
+									: binding.getBindValue();
 					final JdbcParameterImpl jdbcParameter = new JdbcParameterImpl( jdbcMapping );
 					jdbcParameterBinders.add( jdbcParameter );
-					addBinding(
-							jdbcParameter,
-							new JdbcParameterBindingImpl( jdbcMapping, bindValue )
-					);
+					addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, bindValue ) );
 				}
 			}
 		}
 	}
 
-	private BindableType> determineParamType(QueryParameterImplementor> param, QueryParameterBinding> binding) {
-		BindableType> type = binding.getBindType();
+	private JdbcMapping jdbcMapping(SessionFactoryImplementor factory, QueryParameterImplementor> param, QueryParameterBinding> binding) {
+		final BindableType> type = determineParamType( param, binding );
 		if ( type == null ) {
-			type = param.getHibernateType();
+			return factory.getTypeConfiguration().getBasicTypeForJavaType( Object.class );
 		}
-		return type;
+		else if ( type instanceof BasicTypeReference> basicTypeReference ) {
+			return factory.getTypeConfiguration().getBasicTypeRegistry()
+					.resolve( basicTypeReference );
+		}
+		else if ( type instanceof BasicValuedMapping basicValuedMapping ) {
+			return basicValuedMapping.getJdbcMapping();
+		}
+		else {
+			throw new IllegalArgumentException( "Could not resolve NativeQuery parameter type : `" + param + "`");
+		}
+	}
+
+	private BindableType> determineParamType(QueryParameterImplementor> param, QueryParameterBinding> binding) {
+		final BindableType> type = binding.getBindType();
+		return type == null ? param.getHibernateType() : type;
 	}
 
 	@Override
@@ -157,24 +144,20 @@ public void addBinding(JdbcParameter parameter, JdbcParameterBinding binding) {
 
 	@Override
 	public Collection getBindings() {
-		return bindingMap == null ? Collections.emptyList() : bindingMap.values();
+		return bindingMap == null ? emptyList() : bindingMap.values();
 	}
 
 	@Override
 	public JdbcParameterBinding getBinding(JdbcParameter parameter) {
-		if ( bindingMap == null ) {
-			return null;
-		}
-		return bindingMap.get( parameter );
+		return bindingMap == null ? null : bindingMap.get( parameter );
 	}
 
 	@Override
 	public void visitBindings(BiConsumer action) {
-		if ( bindingMap == null ) {
-			return;
-		}
-		for ( Map.Entry entry : bindingMap.entrySet() ) {
-			action.accept( entry.getKey(), entry.getValue() );
+		if ( bindingMap != null ) {
+			for ( var entry : bindingMap.entrySet() ) {
+				action.accept( entry.getKey(), entry.getValue() );
+			}
 		}
 	}
 
diff --git a/hibernate-core/src/main/java/org/hibernate/type/Type.java b/hibernate-core/src/main/java/org/hibernate/type/Type.java
index 9e60a82c7c00..34353ee33300 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/Type.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/Type.java
@@ -10,7 +10,6 @@
 import java.util.Map;
 
 import org.hibernate.HibernateException;
-import org.hibernate.Internal;
 import org.hibernate.MappingException;
 import org.hibernate.engine.spi.SessionFactoryImplementor;
 import org.hibernate.engine.spi.SharedSessionContractImplementor;
@@ -32,10 +31,17 @@
  * An implementation of this interface must certainly be thread-safe. Ideally, it should also be
  * immutable.
  *
+ * @apiNote
+ * This interface—which has existed since the very earliest days of Hibernate—used
+ * to be an important API. In modern versions of Hibernate its role has evolved, and it is no
+ * longer considered an API, though it's still a very important SPI. Application programs should
+ * avoid direct use of this interface where possible. In many cases,
+ * {@link org.hibernate.type.descriptor.java.JavaType} or
+ * {@link org.hibernate.type.descriptor.jdbc.JdbcType} may be used instead.
+ *
  * @author Gavin King
  * @author Steve Ebersole
  */
-@Internal
 public interface Type extends Serializable {
 	/**
 	 * Return true if the implementation is castable to {@link AssociationType}. This does not