Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/Interceptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <p>
* 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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
*
Expand All @@ -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 )
);
}

Expand Down Expand Up @@ -99,12 +102,12 @@ public JdbcCallFunctionReturn getFunctionReturn() {

@Override
public List<JdbcCallParameterRegistration> getParameterRegistrations() {
return parameterRegistrations == null ? Collections.emptyList() : parameterRegistrations;
return parameterRegistrations == null ? emptyList() : parameterRegistrations;
}

@Override
public List<JdbcParameterBinder> getParameterBinders() {
return parameterBinders == null ? Collections.emptyList() : parameterBinders;
return parameterBinders == null ? emptyList() : parameterBinders;
}

@Override
Expand All @@ -119,7 +122,7 @@ public boolean dependsOnParameterBindings() {

@Override
public Map<JdbcParameter, JdbcParameterBinding> getAppliedParameters() {
return Collections.emptyMap();
return emptyMap();
}

@Override
Expand All @@ -130,12 +133,12 @@ public boolean isCompatibleWith(

@Override
public List<JdbcCallParameterExtractor> getParameterExtractors() {
return parameterExtractors == null ? Collections.emptyList() : parameterExtractors;
return parameterExtractors == null ? emptyList() : parameterExtractors;
}

@Override
public List<JdbcCallRefCursorExtractor> getCallRefCursorExtractors() {
return refCursorExtractors == null ? Collections.emptyList() : refCursorExtractors;
return refCursorExtractors == null ? emptyList() : refCursorExtractors;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,18 @@
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;
import org.hibernate.type.BindableType;
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;
Expand All @@ -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
*
Expand All @@ -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 ) {
Expand Down Expand Up @@ -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
Expand All @@ -157,24 +144,20 @@ public void addBinding(JdbcParameter parameter, JdbcParameterBinding binding) {

@Override
public Collection<JdbcParameterBinding> 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<JdbcParameter, JdbcParameterBinding> action) {
if ( bindingMap == null ) {
return;
}
for ( Map.Entry<JdbcParameter, JdbcParameterBinding> entry : bindingMap.entrySet() ) {
action.accept( entry.getKey(), entry.getValue() );
if ( bindingMap != null ) {
for ( var entry : bindingMap.entrySet() ) {
action.accept( entry.getKey(), entry.getValue() );
}
}
}

Expand Down
10 changes: 8 additions & 2 deletions hibernate-core/src/main/java/org/hibernate/type/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,10 +31,17 @@
* An implementation of this interface must certainly be thread-safe. Ideally, it should also be
* immutable.
*
* @apiNote
* This interface&mdash;which has existed since the very earliest days of Hibernate&mdash;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
Expand Down
Loading