Implementing ProcedureParamBindings
This commit is contained in:
parent
d4007c5071
commit
6931635c4f
|
@ -31,48 +31,47 @@ public class PostgresCallableStatementSupport implements CallableStatementSuppor
|
|||
ParameterMetadataImplementor parameterMetadata,
|
||||
ProcedureParamBindings paramBindings,
|
||||
SharedSessionContractImplementor session) {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
|
||||
// // if there are any parameters, see if the first is REF_CURSOR
|
||||
// final boolean firstParamIsRefCursor = ! parameterRegistrations.isEmpty()
|
||||
// && parameterRegistrations.get( 0 ).getMode() == ParameterMode.REF_CURSOR;
|
||||
//
|
||||
// if ( firstParamIsRefCursor ) {
|
||||
// // validate that the parameter strategy is positional (cannot mix, and REF_CURSOR is inherently positional)
|
||||
// if ( parameterStrategy == ParameterStrategy.NAMED ) {
|
||||
// throw new HibernateException( "Cannot mix named parameters and REF_CURSOR parameter on PostgreSQL" );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// final StringBuilder buffer;
|
||||
// if ( firstParamIsRefCursor ) {
|
||||
// buffer = new StringBuilder().append( "{? = call " );
|
||||
// }
|
||||
// else {
|
||||
// buffer = new StringBuilder().append( "{call " );
|
||||
// }
|
||||
//
|
||||
// buffer.append( procedureName ).append( "(" );
|
||||
//
|
||||
// String sep = "";
|
||||
//
|
||||
// // skip the first registration if it was a REF_CURSOR
|
||||
// final int startIndex = firstParamIsRefCursor ? 1 : 0;
|
||||
// for ( int i = startIndex; i < parameterRegistrations.size(); i++ ) {
|
||||
// final ParameterRegistrationImplementor parameter = parameterRegistrations.get( i );
|
||||
//
|
||||
// // any additional REF_CURSOR parameter registrations are an error
|
||||
// if ( parameter.getMode() == ParameterMode.REF_CURSOR ) {
|
||||
// throw new HibernateException( "PostgreSQL supports only one REF_CURSOR parameter, but multiple were registered" );
|
||||
// }
|
||||
//
|
||||
// for ( int ignored : parameter.getSqlTypes() ) {
|
||||
// buffer.append( sep ).append( "?" );
|
||||
// sep = ",";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return buffer.append( ")}" ).toString();
|
||||
// if there are any parameters, see if the first is REF_CURSOR
|
||||
final boolean firstParamIsRefCursor = parameterMetadata.getParameterCount() != 0
|
||||
&& paramBindings..getMode() == ParameterMode.REF_CURSOR;
|
||||
|
||||
if ( firstParamIsRefCursor ) {
|
||||
// validate that the parameter strategy is positional (cannot mix, and REF_CURSOR is inherently positional)
|
||||
if ( parameterStrategy == ParameterStrategy.NAMED ) {
|
||||
throw new HibernateException( "Cannot mix named parameters and REF_CURSOR parameter on PostgreSQL" );
|
||||
}
|
||||
}
|
||||
|
||||
final StringBuilder buffer;
|
||||
if ( firstParamIsRefCursor ) {
|
||||
buffer = new StringBuilder().append( "{? = call " );
|
||||
}
|
||||
else {
|
||||
buffer = new StringBuilder().append( "{call " );
|
||||
}
|
||||
|
||||
buffer.append( procedureName ).append( "(" );
|
||||
|
||||
String sep = "";
|
||||
|
||||
// skip the first registration if it was a REF_CURSOR
|
||||
final int startIndex = firstParamIsRefCursor ? 1 : 0;
|
||||
for ( int i = startIndex; i < parameterRegistrations.size(); i++ ) {
|
||||
final ParameterRegistrationImplementor parameter = parameterRegistrations.get( i );
|
||||
|
||||
// any additional REF_CURSOR parameter registrations are an error
|
||||
if ( parameter.getMode() == ParameterMode.REF_CURSOR ) {
|
||||
throw new HibernateException( "PostgreSQL supports only one REF_CURSOR parameter, but multiple were registered" );
|
||||
}
|
||||
|
||||
for ( int ignored : parameter.getSqlTypes() ) {
|
||||
buffer.append( sep ).append( "?" );
|
||||
sep = ",";
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.append( ")}" ).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.procedure.internal;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
|
@ -14,6 +16,7 @@ import java.util.Date;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
import jakarta.persistence.FlushModeType;
|
||||
import jakarta.persistence.LockModeType;
|
||||
|
@ -27,7 +30,6 @@ import jakarta.persistence.TransactionRequiredException;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
@ -62,8 +64,11 @@ import org.hibernate.result.Output;
|
|||
import org.hibernate.result.ResultSetOutput;
|
||||
import org.hibernate.result.UpdateCountOutput;
|
||||
import org.hibernate.result.spi.ResultContext;
|
||||
import org.hibernate.sql.exec.spi.JdbcCall;
|
||||
import org.hibernate.sql.results.NoMoreOutputsException;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Standard implementation of {@link ProcedureCall}
|
||||
*
|
||||
|
@ -72,6 +77,7 @@ import org.hibernate.sql.results.NoMoreOutputsException;
|
|||
public class ProcedureCallImpl<R>
|
||||
extends AbstractQuery<R>
|
||||
implements ProcedureCallImplementor<R>, ResultContext {
|
||||
private static final Logger LOG = Logger.getLogger( ProcedureCallImpl.class );
|
||||
|
||||
private final String procedureName;
|
||||
|
||||
|
@ -432,51 +438,51 @@ public class ProcedureCallImpl<R>
|
|||
// both: (1) add the `? = ` part and also (2) register a REFCURSOR parameter for DBs (Oracle, PGSQL) that
|
||||
// need it.
|
||||
|
||||
// final String call = getSession().getJdbcServices().getJdbcEnvironment().getDialect().getCallableStatementSupport().renderCallableStatement(
|
||||
// procedureName,
|
||||
// getParameterMetadata(),
|
||||
// paramBindings,
|
||||
// getSession()
|
||||
// );
|
||||
//
|
||||
// LOG.debugf( "Preparing procedure call : %s", call );
|
||||
// final CallableStatement statement = (CallableStatement) getSession()
|
||||
// .getJdbcCoordinator()
|
||||
// .getStatementPreparer()
|
||||
// .prepareStatement( call, true );
|
||||
//
|
||||
//
|
||||
// // prepare parameters
|
||||
//
|
||||
// getParameterMetadata().visitRegistrations(
|
||||
// new Consumer<QueryParameter<?>>() {
|
||||
// int i = 1;
|
||||
//
|
||||
// @Override
|
||||
// public void accept(QueryParameter queryParameter) {
|
||||
// try {
|
||||
// final ProcedureParameterImplementor registration = (ProcedureParameterImplementor) queryParameter;
|
||||
// registration.prepare( statement, i, ProcedureCallImpl.this );
|
||||
final JdbcCall call = getSession().getJdbcServices().getJdbcEnvironment().getDialect().getCallableStatementSupport().interpretCall(
|
||||
procedureName,
|
||||
functionReturn,
|
||||
getParameterMetadata(),
|
||||
paramBindings,
|
||||
getSession()
|
||||
);
|
||||
|
||||
LOG.debugf( "Preparing procedure call : %s", call );
|
||||
final CallableStatement statement = (CallableStatement) getSession()
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( call.getSql(), true );
|
||||
|
||||
|
||||
// prepare parameters
|
||||
|
||||
getParameterMetadata().visitRegistrations(
|
||||
new Consumer<QueryParameter<?>>() {
|
||||
int i = 1;
|
||||
|
||||
@Override
|
||||
public void accept(QueryParameter queryParameter) {
|
||||
try {
|
||||
final ProcedureParameterImplementor registration = (ProcedureParameterImplementor) queryParameter;
|
||||
registration.prepare( statement, i, ProcedureCallImpl.this );
|
||||
// if ( registration.getMode() == ParameterMode.REF_CURSOR ) {
|
||||
// i++;
|
||||
i++;
|
||||
// }
|
||||
// else {
|
||||
// i += registration.getSqlTypes().length;
|
||||
// }
|
||||
// }
|
||||
// catch (SQLException e) {
|
||||
// throw getSession().getJdbcServices().getSqlExceptionHelper().convert(
|
||||
// e,
|
||||
// "Error preparing registered callable parameter",
|
||||
// getProcedureName()
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
//
|
||||
// return new ProcedureOutputsImpl( this, statement );
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw getSession().getJdbcServices().getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Error preparing registered callable parameter",
|
||||
getProcedureName()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return new ProcedureOutputsImpl( this, statement );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.hibernate.NotYetImplementedFor6Exception;
|
|||
import org.hibernate.procedure.spi.ProcedureParameterBindingImplementor;
|
||||
import org.hibernate.procedure.spi.ProcedureParameterImplementor;
|
||||
import org.hibernate.query.procedure.ProcedureParameterBinding;
|
||||
import org.hibernate.query.spi.QueryParameterBinding;
|
||||
import org.hibernate.query.spi.QueryParameterBindingTypeResolver;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
import org.hibernate.query.spi.QueryParameterImplementor;
|
||||
|
@ -45,17 +44,16 @@ public class ProcedureParamBindings implements QueryParameterBindings {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <P> QueryParameterBinding<P> getBinding(QueryParameterImplementor<P> parameter) {
|
||||
// return getBinding( parameterMetadata.resolve( parameter ) );
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
public <P> ProcedureParameterBinding<P> getBinding(QueryParameterImplementor<P> parameter) {
|
||||
return getQueryParamerBinding( (ProcedureParameterImplementor) parameter );
|
||||
}
|
||||
|
||||
public ProcedureParameterBindingImplementor<?> getBinding(ProcedureParameterImplementor<?> parameter) {
|
||||
public <P> ProcedureParameterBinding<P> getQueryParamerBinding(ProcedureParameterImplementor<P> parameter) {
|
||||
final ProcedureParameterImplementor procParam = parameterMetadata.resolve( parameter );
|
||||
ProcedureParameterBindingImplementor binding = bindingMap.get( procParam );
|
||||
|
||||
if ( binding == null ) {
|
||||
if ( ! parameterMetadata.containsReference( parameter ) ) {
|
||||
if ( !parameterMetadata.containsReference( parameter ) ) {
|
||||
throw new IllegalArgumentException( "Passed parameter is not registered with this query" );
|
||||
}
|
||||
|
||||
|
@ -68,15 +66,23 @@ public class ProcedureParamBindings implements QueryParameterBindings {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ProcedureParameterBinding<?> getBinding(String name) {
|
||||
// return (ProcedureParameterBinding<?>) getBinding( parameterMetadata.getQueryParameter( name ) );
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
public <P> ProcedureParameterBinding<P> getBinding(String name) {
|
||||
final ProcedureParameterImplementor<P> parameter = (ProcedureParameterImplementor<P>) parameterMetadata
|
||||
.getQueryParameter( name );
|
||||
if ( parameter == null ) {
|
||||
throw new IllegalArgumentException( "Parameter does not exist: " + name );
|
||||
}
|
||||
return getQueryParamerBinding( parameter );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureParameterBinding getBinding(int position) {
|
||||
// return getBinding( parameterMetadata.getQueryParameter( position ) );
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
public <P> ProcedureParameterBinding<P> getBinding(int position) {
|
||||
final ProcedureParameterImplementor<P> parameter = (ProcedureParameterImplementor<P>) parameterMetadata
|
||||
.getQueryParameter( position );
|
||||
if ( parameter == null ) {
|
||||
throw new IllegalArgumentException( "Parameter at position " + position + "does not exist" );
|
||||
}
|
||||
return getQueryParamerBinding( parameter );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -101,5 +107,4 @@ public class ProcedureParamBindings implements QueryParameterBindings {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ import org.hibernate.type.YesNoType;
|
|||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.NotImplementedYet;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -74,7 +73,6 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@NotImplementedYet
|
||||
@DomainModel
|
||||
@SessionFactory
|
||||
public class StoredProcedureParameterTypeTest {
|
||||
|
|
Loading…
Reference in New Issue