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
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Supplier;
Expand All @@ -20,6 +19,9 @@

import org.checkerframework.checker.nullness.qual.Nullable;

import static java.util.Collections.emptyMap;
import static java.util.Collections.unmodifiableMap;

/**
* Implementation of FilterImpl. FilterImpl implements the user's
* view into enabled dynamic filters, allowing them to set filter parameter values.
Expand Down Expand Up @@ -88,7 +90,7 @@ public boolean isAppliedToLoadByKey() {
}

public Map<String,?> getParameters() {
return parameters == null ? Collections.emptyMap() : Collections.unmodifiableMap( parameters );
return parameters == null ? emptyMap() : unmodifiableMap( parameters );
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
*/
public interface DiscriminatorSqmPath<T> extends SqmPath<T> {
@Override
default void appendHqlString(StringBuilder sb) {
sb.append( "type(" );
getLhs().appendHqlString( sb );
sb.append( ')' );
default void appendHqlString(StringBuilder hql) {
hql.append( "type(" );
getLhs().appendHqlString( hql );
hql.append( ')' );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
import org.hibernate.procedure.spi.ProcedureCallImplementor;
import org.hibernate.query.BindableType;
import org.hibernate.query.OutputableType;
import org.hibernate.sql.exec.internal.JdbcCallFunctionReturnImpl;
import org.hibernate.sql.exec.internal.JdbcCallFunctionReturnImpl.RefCurserJdbcCallFunctionReturnImpl;
import org.hibernate.sql.exec.internal.JdbcCallFunctionReturnImpl.RegularJdbcCallFunctionReturnImpl;
import org.hibernate.sql.exec.internal.JdbcCallParameterExtractorImpl;
import org.hibernate.sql.exec.internal.JdbcCallRefCursorExtractorImpl;
import org.hibernate.sql.exec.spi.JdbcCallFunctionReturn;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.spi.TypeConfiguration;

import jakarta.persistence.ParameterMode;
Expand All @@ -26,6 +27,7 @@
* @author Steve Ebersole
*/
public class FunctionReturnImpl<T> implements FunctionReturnImplementor<T> {

private final ProcedureCallImplementor<T> procedureCall;
private final int sqlTypeCode;

Expand All @@ -44,37 +46,36 @@ public FunctionReturnImpl(ProcedureCallImplementor<T> procedureCall, OutputableT

@Override
public JdbcCallFunctionReturn toJdbcFunctionReturn(SharedSessionContractImplementor persistenceContext) {
final OutputableType<T> ormType;
final JdbcCallRefCursorExtractorImpl refCursorExtractor;
final JdbcCallParameterExtractorImpl<T> parameterExtractor;

if ( getJdbcTypeCode() == Types.REF_CURSOR ) {
refCursorExtractor = new JdbcCallRefCursorExtractorImpl( 1 );
ormType = null;
parameterExtractor = null;
return new RefCurserJdbcCallFunctionReturnImpl( new JdbcCallRefCursorExtractorImpl( 1 ) );
}
else {
if ( this.ormType != null ) {
ormType = this.ormType;
}
else {
final TypeConfiguration typeConfiguration = persistenceContext.getFactory().getTypeConfiguration();
final JdbcType sqlTypeDescriptor = typeConfiguration.getJdbcTypeRegistry().getDescriptor(
getJdbcTypeCode()
);
final JavaType<?> javaTypeMapping = sqlTypeDescriptor.getJdbcRecommendedJavaTypeMapping(
null,
null,
typeConfiguration
);
//noinspection unchecked
ormType = (OutputableType<T>) typeConfiguration.standardBasicTypeForJavaType( javaTypeMapping.getJavaTypeClass() );
}
parameterExtractor = new JdbcCallParameterExtractorImpl<>( procedureCall.getProcedureName(), null, 1, ormType );
refCursorExtractor = null;
return new RegularJdbcCallFunctionReturnImpl(
getOrmType( persistenceContext ),
new JdbcCallParameterExtractorImpl<T>(
procedureCall.getProcedureName(),
null,
1,
getOrmType( persistenceContext )
)
);
}
}

return new JdbcCallFunctionReturnImpl( ormType, parameterExtractor, refCursorExtractor );
private OutputableType<T> getOrmType(SharedSessionContractImplementor persistenceContext) {
if ( ormType != null ) {
return ormType;
}
else {
final TypeConfiguration typeConfiguration = persistenceContext.getFactory().getTypeConfiguration();
final JavaType<?> javaType =
typeConfiguration.getJdbcTypeRegistry().getDescriptor( getJdbcTypeCode() )
.getJdbcRecommendedJavaTypeMapping( null, null, typeConfiguration );
final BasicType<?> basicType =
typeConfiguration.standardBasicTypeForJavaType( javaType.getJavaTypeClass() );
//noinspection unchecked
return (OutputableType<T>) basicType;
}
}

@Override
Expand Down Expand Up @@ -103,7 +104,7 @@ public ParameterMode getMode() {
}

@Override
public Class getParameterType() {
public Class<T> getParameterType() {
throw new UnsupportedOperationException();
}

Expand All @@ -113,7 +114,7 @@ public void disallowMultiValuedBinding() {
}

@Override
public void applyAnticipatedType(BindableType type) {
public void applyAnticipatedType(BindableType<?> type) {
throw new UnsupportedOperationException();
}

Expand All @@ -124,13 +125,8 @@ public boolean allowsMultiValuedBinding() {

@Override
public NamedCallableQueryMemento.ParameterMemento toMemento() {
return session -> {
if ( ormType != null ) {
return new FunctionReturnImpl<>( procedureCall, ormType );
}
else {
return new FunctionReturnImpl<>( procedureCall, sqlTypeCode );
}
};
return session -> ormType != null
? new FunctionReturnImpl<T>( procedureCall, ormType )
: new FunctionReturnImpl<T>( procedureCall, sqlTypeCode );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ public <P> ProcedureParameterBinding<P> getQueryParamerBinding(ProcedureParamete

@Override
public <P> ProcedureParameterBinding<P> getBinding(String name) {
final ProcedureParameterImplementor<P> parameter = (ProcedureParameterImplementor<P>) parameterMetadata
.getQueryParameter( name );
//noinspection unchecked
final ProcedureParameterImplementor<P> parameter =
(ProcedureParameterImplementor<P>) parameterMetadata.getQueryParameter( name );
if ( parameter == null ) {
throw new IllegalArgumentException( "Parameter does not exist: " + name );
}
Expand All @@ -85,8 +86,9 @@ public <P> ProcedureParameterBinding<P> getBinding(String name) {

@Override
public <P> ProcedureParameterBinding<P> getBinding(int position) {
final ProcedureParameterImplementor<P> parameter = (ProcedureParameterImplementor<P>) parameterMetadata
.getQueryParameter( position );
//noinspection unchecked
final ProcedureParameterImplementor<P> parameter =
(ProcedureParameterImplementor<P>) parameterMetadata.getQueryParameter( position );
if ( parameter == null ) {
throw new IllegalArgumentException( "Parameter at position " + position + "does not exist" );
}
Expand All @@ -95,28 +97,23 @@ public <P> ProcedureParameterBinding<P> getBinding(int position) {

@Override
public void validate() {
parameterMetadata.visitRegistrations(
queryParameter -> {
final ProcedureParameterImplementor procParam = (ProcedureParameterImplementor) queryParameter;
if ( procParam.getMode() == ParameterMode.IN
|| procParam.getMode() == ParameterMode.INOUT ) {
if ( !getBinding( procParam ).isBound() ) {
// depending on "pass nulls" this might be ok...
// for now, just log a warning
if ( procParam.getPosition() != null ) {
LOG.debugf(
"Procedure parameter at position %s is not bound",
procParam.getPosition()
);

}
else {
LOG.debugf( "Procedure parameter %s is not bound", procParam.getName() );
}
}
}
parameterMetadata.visitRegistrations( parameter -> validate( (ProcedureParameterImplementor<?>) parameter ) );
}

private <T> void validate(ProcedureParameterImplementor<T> procParam) {
final ParameterMode mode = procParam.getMode();
if ( mode == ParameterMode.IN || mode == ParameterMode.INOUT ) {
if ( !getBinding( procParam ).isBound() ) {
// depending on "pass nulls" this might be OK - for now, just log a warning
if ( procParam.getPosition() != null ) {
LOG.debugf( "Procedure parameter at position %s is not bound", procParam.getPosition() );

}
else {
LOG.debugf( "Procedure parameter %s is not bound", procParam.getName() );
}
);
}
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,9 @@ public Class<T> getParameterType() {

@Override
public NamedCallableQueryMemento.ParameterMemento toMemento() {
return session -> {
if ( getName() != null ) {
return new ProcedureParameterImpl<>(
getName(),
getMode(),
javaType,
getHibernateType()
);
}
else {
return new ProcedureParameterImpl<>(
getPosition(),
getMode(),
javaType,
getHibernateType()
);
}
};
return session -> isNamed()
? new ProcedureParameterImpl<T>( getName(), getMode(), javaType, getHibernateType() )
: new ProcedureParameterImpl<T>( getPosition(), getMode(), javaType, getHibernateType() );
}

@Override
Expand All @@ -119,17 +104,7 @@ public JdbcCallParameterRegistration toJdbcParameterRegistration(
final QueryParameterBinding<T> binding = procedureCall.getParameterBindings().getBinding( this );
final boolean isNamed = procedureCall.getParameterStrategy() == ParameterStrategy.NAMED && this.name != null;

final BindableType<T> bindableType;
if ( getHibernateType() != null ) {
bindableType = getHibernateType();
}
else if ( binding != null ) {
//noinspection unchecked
bindableType = (BindableType<T>) binding.getBindType();
}
else {
bindableType = null;
}
final BindableType<T> bindableType = getBindableType( binding );

final SharedSessionContractImplementor session = procedureCall.getSession();

Expand All @@ -143,14 +118,11 @@ else if ( binding != null ) {
final JdbcParameterBinder parameterBinder;
final JdbcCallRefCursorExtractorImpl refCursorExtractor;
final JdbcCallParameterExtractorImpl<T> parameterExtractor;
final ExtractedDatabaseMetaData databaseMetaData = session
.getFactory()
.getJdbcServices()
.getJdbcEnvironment()
.getExtractedDatabaseMetaData();
final boolean passProcedureParameterNames = session.getFactory()
.getSessionFactoryOptions()
.isPassProcedureParameterNames();
final ExtractedDatabaseMetaData databaseMetaData =
session.getFactory().getJdbcServices().getJdbcEnvironment()
.getExtractedDatabaseMetaData();
final boolean passProcedureParameterNames =
session.getFactory().getSessionFactoryOptions().isPassProcedureParameterNames();
switch ( mode ) {
case REF_CURSOR:
jdbcParamName = this.name != null && databaseMetaData.supportsNamedParameters() && passProcedureParameterNames ? this.name : null;
Expand Down Expand Up @@ -184,13 +156,29 @@ else if ( binding != null ) {
return new JdbcCallParameterRegistrationImpl( jdbcParamName, startIndex, mode, typeToUse, parameterBinder, parameterExtractor, refCursorExtractor );
}

private BindableType<T> getBindableType(QueryParameterBinding<T> binding) {
if ( getHibernateType() != null ) {
return getHibernateType();
}
else if ( binding != null ) {
//noinspection unchecked
return (BindableType<T>) binding.getBindType();
}
else {
return null;
}
}

private String getJdbcParamName(
ProcedureCallImplementor<?> procedureCall,
boolean isNamed,
boolean passProcedureParameterNames,
OutputableType<T> typeToUse,
ExtractedDatabaseMetaData databaseMetaData) {
return isNamed && passProcedureParameterNames && canDoNameParameterBinding( typeToUse, procedureCall, databaseMetaData ) ? this.name : null;
return isNamed && passProcedureParameterNames
&& canDoNameParameterBinding( typeToUse, procedureCall, databaseMetaData )
? this.name
: null;
}

private void validateBindableType(BindableType<T> bindableType, int startIndex) {
Expand All @@ -217,22 +205,22 @@ private JdbcParameterBinder getParameterBinder(BindableType<T> typeToUse, String
)
);
}

if ( typeToUse instanceof BasicType<?> ) {
else if ( typeToUse instanceof BasicType<?> ) {
return new JdbcParameterImpl( (BasicType<T>) typeToUse );
}

throw new UnsupportedOperationException();
else {
throw new UnsupportedOperationException();
}
}

private boolean canDoNameParameterBinding(
BindableType<?> hibernateType,
ProcedureCallImplementor<?> procedureCall,
ExtractedDatabaseMetaData databaseMetaData) {
return procedureCall.getFunctionReturn() == null
&& databaseMetaData.supportsNamedParameters()
&& hibernateType instanceof ProcedureParameterNamedBinder
&& ( (ProcedureParameterNamedBinder<?>) hibernateType ).canDoSetting();
&& databaseMetaData.supportsNamedParameters()
&& hibernateType instanceof ProcedureParameterNamedBinder
&& ( (ProcedureParameterNamedBinder<?>) hibernateType ).canDoSetting();
}

@Override
Expand All @@ -245,22 +233,19 @@ public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
if ( o == null ) {
return false;
}
if ( !(o instanceof ProcedureParameterImpl<?> that) ) {
return false;
}
ProcedureParameterImpl<?> that = (ProcedureParameterImpl<?>) o;
return Objects.equals( name, that.name ) &&
Objects.equals( position, that.position ) &&
mode == that.mode;
return Objects.equals( name, that.name )
&& Objects.equals( position, that.position )
&& mode == that.mode;
}

@Override
public String toString() {
if ( position == null ) {
return name;
}
else {
return position.toString();
}
return position == null ? name : position.toString();
}
}
Loading
Loading