HHH-7914 - Improve new stored procedure call support
This commit is contained in:
parent
9ce5c32dd7
commit
6062eb67ea
|
@ -25,7 +25,7 @@ package org.hibernate;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.procedure.Call;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
|
||||
/**
|
||||
* Contract methods shared between {@link Session} and {@link StatelessSession}
|
||||
|
@ -93,7 +93,7 @@ public interface SharedSessionContract extends Serializable {
|
|||
*
|
||||
* @return The representation of the procedure call.
|
||||
*/
|
||||
public Call createStoredProcedureCall(String procedureName);
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName);
|
||||
|
||||
/**
|
||||
* Creates a call to a stored procedure with specific result set entity mappings. Each class named
|
||||
|
@ -104,7 +104,7 @@ public interface SharedSessionContract extends Serializable {
|
|||
*
|
||||
* @return The representation of the procedure call.
|
||||
*/
|
||||
public Call createStoredProcedureCall(String procedureName, Class... resultClasses);
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName, Class... resultClasses);
|
||||
|
||||
/**
|
||||
* Creates a call to a stored procedure with specific result set entity mappings
|
||||
|
@ -114,7 +114,7 @@ public interface SharedSessionContract extends Serializable {
|
|||
*
|
||||
* @return The representation of the procedure call.
|
||||
*/
|
||||
public Call createStoredProcedureCall(String procedureName, String... resultSetMappings);
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName, String... resultSetMappings);
|
||||
|
||||
/**
|
||||
* Create {@link Criteria} instance for the given class (entity or subclasses/implementors)
|
||||
|
|
|
@ -37,7 +37,7 @@ import org.hibernate.SQLQuery;
|
|||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.SessionException;
|
||||
import org.hibernate.SharedSessionContract;
|
||||
import org.hibernate.procedure.Call;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.cache.spi.CacheKey;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
|
@ -59,7 +59,7 @@ import org.hibernate.jdbc.WorkExecutorVisitable;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||
import org.hibernate.procedure.internal.CallImpl;
|
||||
import org.hibernate.procedure.internal.ProcedureCallImpl;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
|
@ -241,29 +241,29 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
public Call createStoredProcedureCall(String procedureName) {
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName) {
|
||||
errorIfClosed();
|
||||
final Call call = new CallImpl( this, procedureName );
|
||||
final ProcedureCall procedureCall = new ProcedureCallImpl( this, procedureName );
|
||||
// call.setComment( "Dynamic stored procedure call" );
|
||||
return call;
|
||||
return procedureCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
public Call createStoredProcedureCall(String procedureName, Class... resultClasses) {
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName, Class... resultClasses) {
|
||||
errorIfClosed();
|
||||
final Call call = new CallImpl( this, procedureName, resultClasses );
|
||||
final ProcedureCall procedureCall = new ProcedureCallImpl( this, procedureName, resultClasses );
|
||||
// call.setComment( "Dynamic stored procedure call" );
|
||||
return call;
|
||||
return procedureCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
public Call createStoredProcedureCall(String procedureName, String... resultSetMappings) {
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName, String... resultSetMappings) {
|
||||
errorIfClosed();
|
||||
final Call call = new CallImpl( this, procedureName, resultSetMappings );
|
||||
final ProcedureCall procedureCall = new ProcedureCallImpl( this, procedureName, resultSetMappings );
|
||||
// call.setComment( "Dynamic stored procedure call" );
|
||||
return call;
|
||||
return procedureCall;
|
||||
}
|
||||
|
||||
protected HQLQueryPlan getHQLQueryPlan(String query, boolean shallow) throws HibernateException {
|
||||
|
|
|
@ -74,6 +74,8 @@ import org.hibernate.ScrollableResults;
|
|||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionBuilder;
|
||||
import org.hibernate.SessionException;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.engine.spi.SessionOwner;
|
||||
import org.hibernate.SharedSessionBuilder;
|
||||
import org.hibernate.SimpleNaturalIdLoadAccess;
|
||||
import org.hibernate.Transaction;
|
||||
|
@ -98,7 +100,6 @@ import org.hibernate.engine.spi.NonFlushedChanges;
|
|||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionOwner;
|
||||
import org.hibernate.engine.spi.Status;
|
||||
import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
|
@ -149,7 +150,6 @@ import org.hibernate.persister.collection.CollectionPersister;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.procedure.Call;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.stat.SessionStatistics;
|
||||
|
@ -1742,21 +1742,21 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
@Override
|
||||
public Call createStoredProcedureCall(String procedureName) {
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName) {
|
||||
errorIfClosed();
|
||||
checkTransactionSynchStatus();
|
||||
return super.createStoredProcedureCall( procedureName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Call createStoredProcedureCall(String procedureName, String... resultSetMappings) {
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName, String... resultSetMappings) {
|
||||
errorIfClosed();
|
||||
checkTransactionSynchStatus();
|
||||
return super.createStoredProcedureCall( procedureName, resultSetMappings );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Call createStoredProcedureCall(String procedureName, Class... resultClasses) {
|
||||
public ProcedureCall createStoredProcedureCall(String procedureName, Class... resultClasses) {
|
||||
errorIfClosed();
|
||||
checkTransactionSynchStatus();
|
||||
return super.createStoredProcedureCall( procedureName, resultClasses );
|
||||
|
|
|
@ -35,15 +35,15 @@ import org.hibernate.SynchronizeableQuery;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Call extends BasicQueryContract, SynchronizeableQuery {
|
||||
public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery {
|
||||
@Override
|
||||
public Call addSynchronizedQuerySpace(String querySpace);
|
||||
public ProcedureCall addSynchronizedQuerySpace(String querySpace);
|
||||
|
||||
@Override
|
||||
public Call addSynchronizedEntityName(String entityName) throws MappingException;
|
||||
public ProcedureCall addSynchronizedEntityName(String entityName) throws MappingException;
|
||||
|
||||
@Override
|
||||
public Call addSynchronizedEntityClass(Class entityClass) throws MappingException;
|
||||
public ProcedureCall addSynchronizedEntityClass(Class entityClass) throws MappingException;
|
||||
|
||||
/**
|
||||
* Get the name of the stored procedure to be called.
|
||||
|
@ -72,7 +72,7 @@ public interface Call extends BasicQueryContract, SynchronizeableQuery {
|
|||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public Call registerParameter0(int position, Class type, ParameterMode mode);
|
||||
public ProcedureCall registerParameter0(int position, Class type, ParameterMode mode);
|
||||
|
||||
/**
|
||||
* Retrieve a previously registered parameter memento by the position under which it was registered.
|
||||
|
@ -104,7 +104,7 @@ public interface Call extends BasicQueryContract, SynchronizeableQuery {
|
|||
*
|
||||
* @return The parameter registration memento
|
||||
*/
|
||||
public Call registerParameter0(String parameterName, Class type, ParameterMode mode)
|
||||
public ProcedureCall registerParameter0(String parameterName, Class type, ParameterMode mode)
|
||||
throws NamedParametersNotSupportedException;
|
||||
|
||||
/**
|
||||
|
@ -131,6 +131,6 @@ public interface Call extends BasicQueryContract, SynchronizeableQuery {
|
|||
*
|
||||
* @return The outputs representation
|
||||
*/
|
||||
public Outputs getOutputs();
|
||||
public ProcedureResult getResult();
|
||||
|
||||
}
|
|
@ -23,14 +23,15 @@
|
|||
*/
|
||||
package org.hibernate.procedure;
|
||||
|
||||
import org.hibernate.result.Result;
|
||||
|
||||
/**
|
||||
* Represents all the outputs of a call to a database stored procedure (or function) through the JDBC
|
||||
* {@link java.sql.CallableStatement} interface.
|
||||
* Specialization of the {@link Result} contract providing access to the stored procedure's registered
|
||||
* output parameters.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Outputs {
|
||||
|
||||
public interface ProcedureResult extends Result {
|
||||
/**
|
||||
* Retrieve the value of an OUTPUT parameter by the parameter's registration memento.
|
||||
* <p/>
|
||||
|
@ -41,7 +42,7 @@ public interface Outputs {
|
|||
*
|
||||
* @return The output value.
|
||||
*
|
||||
* @see Call#registerParameter(String, Class, javax.persistence.ParameterMode)
|
||||
* @see ProcedureCall#registerParameter(String, Class, javax.persistence.ParameterMode)
|
||||
*/
|
||||
public <T> T getOutputParameterValue(ParameterRegistration<T> parameterRegistration);
|
||||
|
||||
|
@ -52,7 +53,7 @@ public interface Outputs {
|
|||
*
|
||||
* @return The output value.
|
||||
*
|
||||
* @see Call#registerParameter(String, Class, javax.persistence.ParameterMode)
|
||||
* @see ProcedureCall#registerParameter(String, Class, javax.persistence.ParameterMode)
|
||||
*/
|
||||
public Object getOutputParameterValue(String name);
|
||||
|
||||
|
@ -63,22 +64,7 @@ public interface Outputs {
|
|||
*
|
||||
* @return The output value.
|
||||
*
|
||||
* @see Call#registerParameter(int, Class, javax.persistence.ParameterMode)
|
||||
* @see ProcedureCall#registerParameter(int, Class, javax.persistence.ParameterMode)
|
||||
*/
|
||||
public Object getOutputParameterValue(int position);
|
||||
|
||||
/**
|
||||
* Are there any more returns associated with this set of outputs?
|
||||
*
|
||||
* @return {@code true} means there are more results available via {@link #getNextReturn()}; {@code false}
|
||||
* indicates that calling {@link #getNextReturn()} will certainly result in an exception.
|
||||
*/
|
||||
public boolean hasMoreReturns();
|
||||
|
||||
/**
|
||||
* Retrieve the next return.
|
||||
*
|
||||
* @return The next return.
|
||||
*/
|
||||
public Return getNextReturn();
|
||||
}
|
|
@ -48,7 +48,7 @@ import org.hibernate.type.Type;
|
|||
public abstract class AbstractParameterRegistrationImpl<T> implements ParameterRegistrationImplementor<T> {
|
||||
private static final Logger log = Logger.getLogger( AbstractParameterRegistrationImpl.class );
|
||||
|
||||
private final CallImpl procedureCall;
|
||||
private final ProcedureCallImpl procedureCall;
|
||||
|
||||
private final Integer position;
|
||||
private final String name;
|
||||
|
@ -63,7 +63,7 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
private int[] sqlTypes;
|
||||
|
||||
protected AbstractParameterRegistrationImpl(
|
||||
CallImpl procedureCall,
|
||||
ProcedureCallImpl procedureCall,
|
||||
Integer position,
|
||||
Class<T> type,
|
||||
ParameterMode mode) {
|
||||
|
@ -71,7 +71,7 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
}
|
||||
|
||||
protected AbstractParameterRegistrationImpl(
|
||||
CallImpl procedureCall,
|
||||
ProcedureCallImpl procedureCall,
|
||||
String name,
|
||||
Class<T> type,
|
||||
ParameterMode mode) {
|
||||
|
@ -79,7 +79,7 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
}
|
||||
|
||||
private AbstractParameterRegistrationImpl(
|
||||
CallImpl procedureCall,
|
||||
ProcedureCallImpl procedureCall,
|
||||
Integer position,
|
||||
String name,
|
||||
Class<T> type,
|
||||
|
@ -96,7 +96,7 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
}
|
||||
|
||||
protected SessionImplementor session() {
|
||||
return procedureCall.session();
|
||||
return procedureCall.getSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -258,7 +258,7 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
|
|||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw procedureCall.session().getFactory().getSQLExceptionHelper().convert(
|
||||
throw procedureCall.getSession().getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
"Unable to extract OUT/INOUT parameter value"
|
||||
);
|
||||
|
|
|
@ -30,7 +30,7 @@ import javax.persistence.ParameterMode;
|
|||
*/
|
||||
public class NamedParameterRegistration<T> extends AbstractParameterRegistrationImpl<T> {
|
||||
public NamedParameterRegistration(
|
||||
CallImpl procedureCall,
|
||||
ProcedureCallImpl procedureCall,
|
||||
String name,
|
||||
Class<T> type,
|
||||
ParameterMode mode) {
|
||||
|
|
|
@ -30,7 +30,7 @@ import javax.persistence.ParameterMode;
|
|||
*/
|
||||
public class PositionalParameterRegistration<T> extends AbstractParameterRegistrationImpl<T> {
|
||||
public PositionalParameterRegistration(
|
||||
CallImpl procedureCall,
|
||||
ProcedureCallImpl procedureCall,
|
||||
Integer position,
|
||||
Class<T> type,
|
||||
ParameterMode mode) {
|
||||
|
|
|
@ -28,7 +28,6 @@ import java.sql.CallableStatement;
|
|||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -48,18 +47,19 @@ import org.hibernate.engine.spi.SessionImplementor;
|
|||
import org.hibernate.internal.AbstractBasicQueryContractImpl;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.procedure.Call;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.procedure.NamedParametersNotSupportedException;
|
||||
import org.hibernate.procedure.ParameterRegistration;
|
||||
import org.hibernate.procedure.Outputs;
|
||||
import org.hibernate.procedure.ProcedureResult;
|
||||
import org.hibernate.result.spi.ResultContext;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Standard implementation of {@link Call}
|
||||
* Standard implementation of {@link org.hibernate.procedure.ProcedureCall}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
||||
public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements ProcedureCall, ResultContext {
|
||||
private final String procedureName;
|
||||
private final NativeSQLQueryReturn[] queryReturns;
|
||||
|
||||
|
@ -68,15 +68,15 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
|
||||
private Set<String> synchronizedQuerySpaces;
|
||||
|
||||
private OutputsImpl outputs;
|
||||
private ProcedureResultImpl outputs;
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public CallImpl(SessionImplementor session, String procedureName) {
|
||||
public ProcedureCallImpl(SessionImplementor session, String procedureName) {
|
||||
this( session, procedureName, (List) null );
|
||||
}
|
||||
|
||||
public CallImpl(SessionImplementor session, String procedureName, List<NativeSQLQueryReturn> queryReturns) {
|
||||
public ProcedureCallImpl(SessionImplementor session, String procedureName, List<NativeSQLQueryReturn> queryReturns) {
|
||||
super( session );
|
||||
this.procedureName = procedureName;
|
||||
|
||||
|
@ -88,7 +88,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
}
|
||||
}
|
||||
|
||||
public CallImpl(SessionImplementor session, String procedureName, Class... resultClasses) {
|
||||
public ProcedureCallImpl(SessionImplementor session, String procedureName, Class... resultClasses) {
|
||||
this( session, procedureName, collectQueryReturns( resultClasses ) );
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
return queryReturns;
|
||||
}
|
||||
|
||||
public CallImpl(SessionImplementor session, String procedureName, String... resultSetMappings) {
|
||||
public ProcedureCallImpl(SessionImplementor session, String procedureName, String... resultSetMappings) {
|
||||
this( session, procedureName, collectQueryReturns( session, resultSetMappings ) );
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
return queryReturns;
|
||||
}
|
||||
|
||||
// public CallImpl(
|
||||
// public ProcedureCallImpl(
|
||||
// SessionImplementor session,
|
||||
// String procedureName,
|
||||
// List<StoredProcedureParameter> parameters) {
|
||||
|
@ -139,8 +139,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
// }
|
||||
|
||||
@Override
|
||||
public SessionImplementor session() {
|
||||
// provide access to delegates
|
||||
public SessionImplementor getSession() {
|
||||
return super.session();
|
||||
}
|
||||
|
||||
|
@ -153,7 +152,13 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
return procedureName;
|
||||
}
|
||||
|
||||
NativeSQLQueryReturn[] getQueryReturns() {
|
||||
@Override
|
||||
public String getSql() {
|
||||
return getProcedureName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeSQLQueryReturn[] getQueryReturns() {
|
||||
return queryReturns;
|
||||
}
|
||||
|
||||
|
@ -167,7 +172,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Call registerParameter0(int position, Class type, ParameterMode mode) {
|
||||
public ProcedureCall registerParameter0(int position, Class type, ParameterMode mode) {
|
||||
registerParameter( position, type, mode );
|
||||
return this;
|
||||
}
|
||||
|
@ -198,7 +203,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
}
|
||||
if ( parameterStrategy == null ) {
|
||||
// protect to only do this check once
|
||||
final ExtractedDatabaseMetaData databaseMetaData = session().getTransactionCoordinator()
|
||||
final ExtractedDatabaseMetaData databaseMetaData = getSession().getTransactionCoordinator()
|
||||
.getJdbcCoordinator()
|
||||
.getLogicalConnection()
|
||||
.getJdbcServices()
|
||||
|
@ -235,7 +240,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Call registerParameter0(String name, Class type, ParameterMode mode) {
|
||||
public ProcedureCall registerParameter0(String name, Class type, ParameterMode mode) {
|
||||
registerParameter( name, type, mode );
|
||||
return this;
|
||||
}
|
||||
|
@ -260,7 +265,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Outputs getOutputs() {
|
||||
public ProcedureResult getResult() {
|
||||
if ( outputs == null ) {
|
||||
outputs = buildOutputs();
|
||||
}
|
||||
|
@ -268,7 +273,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
return outputs;
|
||||
}
|
||||
|
||||
private OutputsImpl buildOutputs() {
|
||||
private ProcedureResultImpl buildOutputs() {
|
||||
// todo : going to need a very specialized Loader for this.
|
||||
// or, might be a good time to look at splitting Loader up into:
|
||||
// 1) building statement objects
|
||||
|
@ -291,7 +296,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
buffer.append( ")}" );
|
||||
|
||||
try {
|
||||
final CallableStatement statement = (CallableStatement) session().getTransactionCoordinator()
|
||||
final CallableStatement statement = (CallableStatement) getSession().getTransactionCoordinator()
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( buffer.toString(), true );
|
||||
|
@ -307,10 +312,10 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
i += parameter.getSqlTypes().length;
|
||||
}
|
||||
|
||||
return new OutputsImpl( this, statement );
|
||||
return new ProcedureResultImpl( this, statement );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw session().getFactory().getSQLExceptionHelper().convert(
|
||||
throw getSession().getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
"Error preparing CallableStatement",
|
||||
getProcedureName()
|
||||
|
@ -333,7 +338,7 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<String> getSynchronizedQuerySpaces() {
|
||||
public Set<String> getSynchronizedQuerySpaces() {
|
||||
if ( synchronizedQuerySpaces == null ) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
@ -342,19 +347,15 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
}
|
||||
}
|
||||
|
||||
public Set<String> getSynchronizedQuerySpacesSet() {
|
||||
return (Set<String>) getSynchronizedQuerySpaces();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallImpl addSynchronizedQuerySpace(String querySpace) {
|
||||
public ProcedureCallImpl addSynchronizedQuerySpace(String querySpace) {
|
||||
synchronizedQuerySpaces().add( querySpace );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallImpl addSynchronizedEntityName(String entityName) {
|
||||
addSynchronizedQuerySpaces( session().getFactory().getEntityPersister( entityName ) );
|
||||
public ProcedureCallImpl addSynchronizedEntityName(String entityName) {
|
||||
addSynchronizedQuerySpaces( getSession().getFactory().getEntityPersister( entityName ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -363,11 +364,16 @@ public class CallImpl extends AbstractBasicQueryContractImpl implements Call {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CallImpl addSynchronizedEntityClass(Class entityClass) {
|
||||
addSynchronizedQuerySpaces( session().getFactory().getEntityPersister( entityClass.getName() ) );
|
||||
public ProcedureCallImpl addSynchronizedEntityClass(Class entityClass) {
|
||||
addSynchronizedQuerySpaces( getSession().getFactory().getEntityPersister( entityClass.getName() ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryParameters getQueryParameters() {
|
||||
return buildQueryParametersObject();
|
||||
}
|
||||
|
||||
public QueryParameters buildQueryParametersObject() {
|
||||
QueryParameters qp = super.buildQueryParametersObject();
|
||||
// both of these are for documentation purposes, they are actually handled directly...
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.procedure.internal;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport;
|
||||
import org.hibernate.procedure.ParameterRegistration;
|
||||
import org.hibernate.procedure.ProcedureResult;
|
||||
import org.hibernate.result.Return;
|
||||
import org.hibernate.result.internal.ResultImpl;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ProcedureResultImpl extends ResultImpl implements ProcedureResult {
|
||||
private final ProcedureCallImpl procedureCall;
|
||||
private final CallableStatement callableStatement;
|
||||
|
||||
private final ParameterRegistrationImplementor[] refCursorParameters;
|
||||
private int refCursorParamIndex = 0;
|
||||
|
||||
ProcedureResultImpl(ProcedureCallImpl procedureCall, CallableStatement callableStatement) {
|
||||
super( procedureCall, callableStatement );
|
||||
this.procedureCall = procedureCall;
|
||||
this.callableStatement = callableStatement;
|
||||
|
||||
this.refCursorParameters = procedureCall.collectRefCursorParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getOutputParameterValue(ParameterRegistration<T> parameterRegistration) {
|
||||
return ( (ParameterRegistrationImplementor<T>) parameterRegistration ).extract( callableStatement );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOutputParameterValue(String name) {
|
||||
return procedureCall.getParameterRegistration( name ).extract( callableStatement );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOutputParameterValue(int position) {
|
||||
return procedureCall.getParameterRegistration( position ).extract( callableStatement );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CurrentReturnDescriptor buildCurrentReturnDescriptor(boolean isResultSet, int updateCount) {
|
||||
return new ProcedureCurrentReturnDescriptor( isResultSet, updateCount, refCursorParamIndex );
|
||||
}
|
||||
|
||||
protected boolean hasMoreReturns(CurrentReturnDescriptor descriptor) {
|
||||
return super.hasMoreReturns( descriptor )
|
||||
|| ( (ProcedureCurrentReturnDescriptor) descriptor ).refCursorParamIndex < refCursorParameters.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Return buildExtendedReturn(CurrentReturnDescriptor returnDescriptor) {
|
||||
this.refCursorParamIndex++;
|
||||
ResultSet resultSet;
|
||||
int refCursorParamIndex = ( (ProcedureCurrentReturnDescriptor) returnDescriptor ).refCursorParamIndex;
|
||||
ParameterRegistrationImplementor refCursorParam = refCursorParameters[refCursorParamIndex];
|
||||
if ( refCursorParam.getName() != null ) {
|
||||
resultSet = procedureCall.getSession().getFactory().getServiceRegistry()
|
||||
.getService( RefCursorSupport.class )
|
||||
.getResultSet( callableStatement, refCursorParam.getName() );
|
||||
}
|
||||
else {
|
||||
resultSet = procedureCall.getSession().getFactory().getServiceRegistry()
|
||||
.getService( RefCursorSupport.class )
|
||||
.getResultSet( callableStatement, refCursorParam.getPosition() );
|
||||
}
|
||||
return new ResultSetReturn( this, resultSet );
|
||||
}
|
||||
|
||||
protected JDBCException convert(SQLException e, String message) {
|
||||
return procedureCall.getSession().getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
message,
|
||||
procedureCall.getProcedureName()
|
||||
);
|
||||
}
|
||||
|
||||
protected static class ProcedureCurrentReturnDescriptor extends CurrentReturnDescriptor {
|
||||
private final int refCursorParamIndex;
|
||||
|
||||
private ProcedureCurrentReturnDescriptor(boolean isResultSet, int updateCount, int refCursorParamIndex) {
|
||||
super( isResultSet, updateCount );
|
||||
this.refCursorParamIndex = refCursorParamIndex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,21 +3,21 @@ package org.hibernate.procedure;
|
|||
/**
|
||||
* Defines support for executing database stored procedures and functions and accessing its outputs.
|
||||
* <p/>
|
||||
* First a reference to {@link Call} is obtained through one of the overloaded
|
||||
* {@link org.hibernate.Session#createStoredProcedureCall} methods. The Call reference is then used to "configure"
|
||||
* First a reference to {@link ProcedureCall} is obtained through one of the overloaded
|
||||
* {@link org.hibernate.Session#createStoredProcedureCall} methods. The ProcedureCall reference is then used to "configure"
|
||||
* the procedure call (set timeouts, etc) and to perform parameter registration. All procedure parameters that the
|
||||
* application wants to use must be registered. For all IN and INOUT parameters, values can then be bound.
|
||||
* <p/>
|
||||
* At this point we are ready to execute the procedure call and start accessing the outputs. This is done by first
|
||||
* calling the {@link Call#getOutputs()} method. The underlying JDBC call is executed as needed. The pattern to
|
||||
* access the returns is iterating through the outputs while {@link Outputs#hasMoreReturns()} returns {@code true} and
|
||||
* calling {@link Outputs#getNextReturn()} during iteration:
|
||||
* calling the {@link ProcedureCall#getResult()} method. The underlying JDBC call is executed as needed. The pattern to
|
||||
* access the returns is iterating through the outputs while {@link ProcedureResult#hasMoreReturns()} returns {@code true} and
|
||||
* calling {@link ProcedureResult#getNextReturn()} during iteration:
|
||||
* <code>
|
||||
* Call call = session.createStoredProcedureCall( "some_procedure" );
|
||||
* ProcedureCall call = session.createStoredProcedureCall( "some_procedure" );
|
||||
* ...
|
||||
* Outputs = call.getOutputs();
|
||||
* while ( call.hasMoreReturns() ) {
|
||||
* final Return rtn = call.getNextReturn();
|
||||
* ProcedureResult result = call.getResult();
|
||||
* while ( result.hasMoreReturns() ) {
|
||||
* final Return rtn = result.getNextReturn();
|
||||
* if ( rtn.isResultSet() ) {
|
||||
* handleResultSetReturn( (ResultSetReturn) rtn );
|
||||
* }
|
||||
|
@ -27,7 +27,7 @@ package org.hibernate.procedure;
|
|||
* }
|
||||
* </code>
|
||||
* <p/>
|
||||
* Finally output parameters can be accessed using the overloaded {@link Outputs#getOutputParameterValue} methods.
|
||||
* Finally output parameters can be accessed using the overloaded {@link ProcedureResult#getOutputParameterValue} methods.
|
||||
* For portability amongst databases, it is advised to access the output parameters after all returns have been
|
||||
* processed.
|
||||
*
|
||||
|
|
|
@ -21,10 +21,15 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.procedure;
|
||||
package org.hibernate.result;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface InOutParameterRegistration<T> extends InParameterRegistration<T>, OutParameterRegistration<T> {
|
||||
public class NoMoreReturnsException extends HibernateException {
|
||||
public NoMoreReturnsException(String message) {
|
||||
super( message );
|
||||
}
|
||||
}
|
|
@ -21,10 +21,30 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.procedure;
|
||||
package org.hibernate.result;
|
||||
|
||||
/**
|
||||
* Represents the result of executing a JDBC statement accounting for mixing of result sets and update counts hiding the
|
||||
* complexity (IMO) of how this is exposed in the JDBC API.
|
||||
*
|
||||
* A result is made up of group of {@link Return} objects, each representing a single result set or update count.
|
||||
* Conceptually, Result presents those Returns as an iterator.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface OutParameterRegistration<T> extends ParameterRegistration<T> {
|
||||
public interface Result {
|
||||
/**
|
||||
* Are there any more returns associated with this result?
|
||||
*
|
||||
* @return {@code true} means there are more returns available via {@link #getNextReturn()}; {@code false}
|
||||
* indicates that calling {@link #getNextReturn()} will certainly result in an exception.
|
||||
*/
|
||||
public boolean hasMoreReturns();
|
||||
|
||||
/**
|
||||
* Retrieve the next return.
|
||||
*
|
||||
* @return The next return.
|
||||
*/
|
||||
public Return getNextReturn() throws NoMoreReturnsException;
|
||||
}
|
|
@ -21,12 +21,12 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.procedure;
|
||||
package org.hibernate.result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Models a stored procedure result that is a result set.
|
||||
* Models a return that is a result set.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
|
@ -21,10 +21,10 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.procedure;
|
||||
package org.hibernate.result;
|
||||
|
||||
/**
|
||||
* Common contract for procedure call results which can be either results ({@link ResultSetReturn}) or update
|
||||
* Common contract for individual return objects which can be either results ({@link ResultSetReturn}) or update
|
||||
* counts ({@link UpdateCountReturn}).
|
||||
*
|
||||
* @author Steve Ebersole
|
|
@ -21,10 +21,10 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.procedure;
|
||||
package org.hibernate.result;
|
||||
|
||||
/**
|
||||
* Models a stored procedure result that is a result set.
|
||||
* Models a return that is an update count (count of rows affected)
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
|
@ -21,9 +21,9 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.procedure.internal;
|
||||
package org.hibernate.result.internal;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
|
@ -32,53 +32,34 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.procedure.Outputs;
|
||||
import org.hibernate.procedure.ParameterRegistration;
|
||||
import org.hibernate.procedure.Return;
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.loader.custom.CustomLoader;
|
||||
import org.hibernate.loader.custom.CustomQuery;
|
||||
import org.hibernate.loader.custom.sql.SQLQueryReturnProcessor;
|
||||
import org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport;
|
||||
import org.hibernate.result.NoMoreReturnsException;
|
||||
import org.hibernate.result.Result;
|
||||
import org.hibernate.result.Return;
|
||||
import org.hibernate.result.spi.ResultContext;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class OutputsImpl implements Outputs {
|
||||
private final CallImpl procedureCall;
|
||||
private final CallableStatement callableStatement;
|
||||
|
||||
private final ParameterRegistrationImplementor[] refCursorParameters;
|
||||
public class ResultImpl implements Result {
|
||||
private final ResultContext context;
|
||||
private final PreparedStatement jdbcStatement;
|
||||
private final CustomLoaderExtension loader;
|
||||
|
||||
private CurrentReturnDescriptor currentReturnDescriptor;
|
||||
|
||||
private boolean executed = false;
|
||||
private int refCursorParamIndex = 0;
|
||||
|
||||
OutputsImpl(CallImpl procedureCall, CallableStatement callableStatement) {
|
||||
this.procedureCall = procedureCall;
|
||||
this.callableStatement = callableStatement;
|
||||
public ResultImpl(ResultContext context, PreparedStatement jdbcStatement) {
|
||||
this.context = context;
|
||||
this.jdbcStatement = jdbcStatement;
|
||||
|
||||
this.refCursorParameters = procedureCall.collectRefCursorParameters();
|
||||
// For now...
|
||||
this.loader = buildSpecializedCustomLoader( procedureCall );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getOutputParameterValue(ParameterRegistration<T> parameterRegistration) {
|
||||
return ( (ParameterRegistrationImplementor<T>) parameterRegistration ).extract( callableStatement );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOutputParameterValue(String name) {
|
||||
return procedureCall.getParameterRegistration( name ).extract( callableStatement );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOutputParameterValue(int position) {
|
||||
return procedureCall.getParameterRegistration( position ).extract( callableStatement );
|
||||
this.loader = buildSpecializedCustomLoader( context );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -88,7 +69,7 @@ public class OutputsImpl implements Outputs {
|
|||
|
||||
if ( executed ) {
|
||||
try {
|
||||
isResultSet = callableStatement.getMoreResults();
|
||||
isResultSet = jdbcStatement.getMoreResults();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convert( e, "Error calling CallableStatement.getMoreResults" );
|
||||
|
@ -96,7 +77,7 @@ public class OutputsImpl implements Outputs {
|
|||
}
|
||||
else {
|
||||
try {
|
||||
isResultSet = callableStatement.execute();
|
||||
isResultSet = jdbcStatement.execute();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convert( e, "Error calling CallableStatement.execute" );
|
||||
|
@ -107,23 +88,26 @@ public class OutputsImpl implements Outputs {
|
|||
int updateCount = -1;
|
||||
if ( ! isResultSet ) {
|
||||
try {
|
||||
updateCount = callableStatement.getUpdateCount();
|
||||
updateCount = jdbcStatement.getUpdateCount();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convert( e, "Error calling CallableStatement.getUpdateCount" );
|
||||
}
|
||||
}
|
||||
|
||||
currentReturnDescriptor = new CurrentReturnDescriptor( isResultSet, updateCount, refCursorParamIndex );
|
||||
currentReturnDescriptor = buildCurrentReturnDescriptor( isResultSet, updateCount );
|
||||
}
|
||||
|
||||
return hasMoreResults( currentReturnDescriptor );
|
||||
return hasMoreReturns( currentReturnDescriptor );
|
||||
}
|
||||
|
||||
private boolean hasMoreResults(CurrentReturnDescriptor descriptor) {
|
||||
protected CurrentReturnDescriptor buildCurrentReturnDescriptor(boolean isResultSet, int updateCount) {
|
||||
return new CurrentReturnDescriptor( isResultSet, updateCount );
|
||||
}
|
||||
|
||||
protected boolean hasMoreReturns(CurrentReturnDescriptor descriptor) {
|
||||
return descriptor.isResultSet
|
||||
|| descriptor.updateCount >= 0
|
||||
|| descriptor.refCursorParamIndex < refCursorParameters.length;
|
||||
|| descriptor.updateCount >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -137,8 +121,8 @@ public class OutputsImpl implements Outputs {
|
|||
}
|
||||
}
|
||||
|
||||
if ( ! hasMoreResults( currentReturnDescriptor ) ) {
|
||||
throw new IllegalStateException( "Results have been exhausted" );
|
||||
if ( ! hasMoreReturns( currentReturnDescriptor ) ) {
|
||||
throw new NoMoreReturnsException( "Results have been exhausted" );
|
||||
}
|
||||
|
||||
CurrentReturnDescriptor copyReturnDescriptor = currentReturnDescriptor;
|
||||
|
@ -146,7 +130,7 @@ public class OutputsImpl implements Outputs {
|
|||
|
||||
if ( copyReturnDescriptor.isResultSet ) {
|
||||
try {
|
||||
return new ResultSetReturn( this, callableStatement.getResultSet() );
|
||||
return new ResultSetReturn( this, jdbcStatement.getResultSet() );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convert( e, "Error calling CallableStatement.getResultSet" );
|
||||
|
@ -156,49 +140,37 @@ public class OutputsImpl implements Outputs {
|
|||
return new UpdateCountReturn( this, copyReturnDescriptor.updateCount );
|
||||
}
|
||||
else {
|
||||
this.refCursorParamIndex++;
|
||||
ResultSet resultSet;
|
||||
int refCursorParamIndex = copyReturnDescriptor.refCursorParamIndex;
|
||||
ParameterRegistrationImplementor refCursorParam = refCursorParameters[refCursorParamIndex];
|
||||
if ( refCursorParam.getName() != null ) {
|
||||
resultSet = procedureCall.session().getFactory().getServiceRegistry()
|
||||
.getService( RefCursorSupport.class )
|
||||
.getResultSet( callableStatement, refCursorParam.getName() );
|
||||
return buildExtendedReturn( copyReturnDescriptor );
|
||||
}
|
||||
else {
|
||||
resultSet = procedureCall.session().getFactory().getServiceRegistry()
|
||||
.getService( RefCursorSupport.class )
|
||||
.getResultSet( callableStatement, refCursorParam.getPosition() );
|
||||
}
|
||||
return new ResultSetReturn( this, resultSet );
|
||||
}
|
||||
|
||||
protected Return buildExtendedReturn(CurrentReturnDescriptor copyReturnDescriptor) {
|
||||
throw new NoMoreReturnsException( "Results have been exhausted" );
|
||||
}
|
||||
|
||||
protected JDBCException convert(SQLException e, String message) {
|
||||
return procedureCall.session().getFactory().getSQLExceptionHelper().convert(
|
||||
return context.getSession().getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
message,
|
||||
procedureCall.getProcedureName()
|
||||
context.getSql()
|
||||
);
|
||||
}
|
||||
|
||||
private static class CurrentReturnDescriptor {
|
||||
protected static class CurrentReturnDescriptor {
|
||||
private final boolean isResultSet;
|
||||
private final int updateCount;
|
||||
private final int refCursorParamIndex;
|
||||
|
||||
private CurrentReturnDescriptor(boolean isResultSet, int updateCount, int refCursorParamIndex) {
|
||||
protected CurrentReturnDescriptor(boolean isResultSet, int updateCount) {
|
||||
this.isResultSet = isResultSet;
|
||||
this.updateCount = updateCount;
|
||||
this.refCursorParamIndex = refCursorParamIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResultSetReturn implements org.hibernate.procedure.ResultSetReturn {
|
||||
private final OutputsImpl storedProcedureOutputs;
|
||||
protected static class ResultSetReturn implements org.hibernate.result.ResultSetReturn {
|
||||
private final ResultImpl storedProcedureOutputs;
|
||||
private final ResultSet resultSet;
|
||||
|
||||
public ResultSetReturn(OutputsImpl storedProcedureOutputs, ResultSet resultSet) {
|
||||
public ResultSetReturn(ResultImpl storedProcedureOutputs, ResultSet resultSet) {
|
||||
this.storedProcedureOutputs = storedProcedureOutputs;
|
||||
this.resultSet = resultSet;
|
||||
}
|
||||
|
@ -231,12 +203,12 @@ public class OutputsImpl implements Outputs {
|
|||
}
|
||||
}
|
||||
|
||||
private class UpdateCountReturn implements org.hibernate.procedure.UpdateCountReturn {
|
||||
private final OutputsImpl procedureOutputs;
|
||||
protected static class UpdateCountReturn implements org.hibernate.result.UpdateCountReturn {
|
||||
private final ResultImpl result;
|
||||
private final int updateCount;
|
||||
|
||||
public UpdateCountReturn(OutputsImpl procedureOutputs, int updateCount) {
|
||||
this.procedureOutputs = procedureOutputs;
|
||||
public UpdateCountReturn(ResultImpl result, int updateCount) {
|
||||
this.result = result;
|
||||
this.updateCount = updateCount;
|
||||
}
|
||||
|
||||
|
@ -251,10 +223,10 @@ public class OutputsImpl implements Outputs {
|
|||
}
|
||||
}
|
||||
|
||||
private static CustomLoaderExtension buildSpecializedCustomLoader(final CallImpl procedureCall) {
|
||||
private static CustomLoaderExtension buildSpecializedCustomLoader(final ResultContext context) {
|
||||
final SQLQueryReturnProcessor processor = new SQLQueryReturnProcessor(
|
||||
procedureCall.getQueryReturns(),
|
||||
procedureCall.session().getFactory()
|
||||
context.getQueryReturns(),
|
||||
context.getSession().getFactory()
|
||||
);
|
||||
processor.process();
|
||||
final List<org.hibernate.loader.custom.Return> customReturns = processor.generateCustomReturns( false );
|
||||
|
@ -262,12 +234,12 @@ public class OutputsImpl implements Outputs {
|
|||
CustomQuery customQuery = new CustomQuery() {
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return procedureCall.getProcedureName();
|
||||
return context.getSql();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getQuerySpaces() {
|
||||
return procedureCall.getSynchronizedQuerySpacesSet();
|
||||
return context.getSynchronizedQuerySpaces();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -284,8 +256,8 @@ public class OutputsImpl implements Outputs {
|
|||
|
||||
return new CustomLoaderExtension(
|
||||
customQuery,
|
||||
procedureCall.buildQueryParametersObject(),
|
||||
procedureCall.session()
|
||||
context.getQueryParameters(),
|
||||
context.getSession()
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package org.hibernate.result;
|
||||
|
||||
/**
|
||||
* Defines support for dealing with database results, accounting for mixed result sets and update counts hiding the
|
||||
* complexity (IMO) of how this is exposed in the JDBC API.
|
||||
*
|
||||
* {@link Result} represents the overall group of results.
|
||||
*
|
||||
* {@link Return} represents the mixed individual outcomes, which might be either a {@link ResultSetReturn} or
|
||||
* a {@link UpdateCountReturn}.
|
||||
*
|
||||
* <code>
|
||||
* Result result = ...;
|
||||
* while ( result.hasMoreReturns() ) {
|
||||
* final Return rtn = result.getNextReturn();
|
||||
* if ( rtn.isResultSet() ) {
|
||||
* handleResultSetReturn( (ResultSetReturn) rtn );
|
||||
* }
|
||||
* else {
|
||||
* handleUpdateCountReturn( (UpdateCountReturn) rtn );
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*/
|
|
@ -21,10 +21,24 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.procedure;
|
||||
package org.hibernate.result.spi;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface InParameterRegistration<T> extends ParameterRegistration<T> {
|
||||
public interface ResultContext {
|
||||
public SessionImplementor getSession();
|
||||
public Set<String> getSynchronizedQuerySpaces();
|
||||
|
||||
// for now...
|
||||
// see Loader-redesign proposal
|
||||
public String getSql();
|
||||
public QueryParameters getQueryParameters();
|
||||
public NativeSQLQueryReturn[] getQueryReturns();
|
||||
}
|
|
@ -32,10 +32,10 @@ import org.hibernate.cfg.Configuration;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.mapping.AuxiliaryDatabaseObject;
|
||||
import org.hibernate.procedure.Call;
|
||||
import org.hibernate.procedure.Outputs;
|
||||
import org.hibernate.procedure.ResultSetReturn;
|
||||
import org.hibernate.procedure.Return;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.procedure.ProcedureResult;
|
||||
import org.hibernate.result.ResultSetReturn;
|
||||
import org.hibernate.result.Return;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
|
||||
import org.junit.Test;
|
||||
|
@ -169,10 +169,10 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
|||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
||||
Call query = session.createStoredProcedureCall( "user");
|
||||
Outputs outputs = query.getOutputs();
|
||||
assertTrue( "Checking Outputs has more returns", outputs.hasMoreReturns() );
|
||||
Return nextReturn = outputs.getNextReturn();
|
||||
ProcedureCall query = session.createStoredProcedureCall( "user");
|
||||
ProcedureResult procedureResult = query.getResult();
|
||||
assertTrue( "Checking ProcedureResult has more returns", procedureResult.hasMoreReturns() );
|
||||
Return nextReturn = procedureResult.getNextReturn();
|
||||
assertNotNull( nextReturn );
|
||||
ExtraAssertions.assertClassAssignability( ResultSetReturn.class, nextReturn.getClass() );
|
||||
ResultSetReturn resultSetReturn = (ResultSetReturn) nextReturn;
|
||||
|
@ -188,10 +188,10 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
|||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
||||
Call query = session.createStoredProcedureCall( "findOneUser" );
|
||||
Outputs outputs = query.getOutputs();
|
||||
assertTrue( "Checking Outputs has more returns", outputs.hasMoreReturns() );
|
||||
Return nextReturn = outputs.getNextReturn();
|
||||
ProcedureCall query = session.createStoredProcedureCall( "findOneUser" );
|
||||
ProcedureResult procedureResult = query.getResult();
|
||||
assertTrue( "Checking ProcedureResult has more returns", procedureResult.hasMoreReturns() );
|
||||
Return nextReturn = procedureResult.getNextReturn();
|
||||
assertNotNull( nextReturn );
|
||||
ExtraAssertions.assertClassAssignability( ResultSetReturn.class, nextReturn.getClass() );
|
||||
ResultSetReturn resultSetReturn = (ResultSetReturn) nextReturn;
|
||||
|
@ -209,10 +209,10 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
|||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
||||
Call query = session.createStoredProcedureCall( "findUsers" );
|
||||
Outputs outputs = query.getOutputs();
|
||||
assertTrue( "Checking Outputs has more returns", outputs.hasMoreReturns() );
|
||||
Return nextReturn = outputs.getNextReturn();
|
||||
ProcedureCall query = session.createStoredProcedureCall( "findUsers" );
|
||||
ProcedureResult procedureResult = query.getResult();
|
||||
assertTrue( "Checking ProcedureResult has more returns", procedureResult.hasMoreReturns() );
|
||||
Return nextReturn = procedureResult.getNextReturn();
|
||||
assertNotNull( nextReturn );
|
||||
ExtraAssertions.assertClassAssignability( ResultSetReturn.class, nextReturn.getClass() );
|
||||
ResultSetReturn resultSetReturn = (ResultSetReturn) nextReturn;
|
||||
|
@ -246,12 +246,12 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
|||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
||||
Call query = session.createStoredProcedureCall( "findUserRange" );
|
||||
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
|
||||
query.registerParameter( "start", Integer.class, ParameterMode.IN ).bindValue( 1 );
|
||||
query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
|
||||
Outputs outputs = query.getOutputs();
|
||||
assertTrue( "Checking Outputs has more returns", outputs.hasMoreReturns() );
|
||||
Return nextReturn = outputs.getNextReturn();
|
||||
ProcedureResult procedureResult = query.getResult();
|
||||
assertTrue( "Checking ProcedureResult has more returns", procedureResult.hasMoreReturns() );
|
||||
Return nextReturn = procedureResult.getNextReturn();
|
||||
assertNotNull( nextReturn );
|
||||
ExtraAssertions.assertClassAssignability( ResultSetReturn.class, nextReturn.getClass() );
|
||||
ResultSetReturn resultSetReturn = (ResultSetReturn) nextReturn;
|
||||
|
@ -273,12 +273,12 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
|||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
||||
Call query = session.createStoredProcedureCall( "findUserRange" );
|
||||
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
|
||||
query.registerParameter( 1, Integer.class, ParameterMode.IN ).bindValue( 1 );
|
||||
query.registerParameter( 2, Integer.class, ParameterMode.IN ).bindValue( 2 );
|
||||
Outputs outputs = query.getOutputs();
|
||||
assertTrue( "Checking Outputs has more returns", outputs.hasMoreReturns() );
|
||||
Return nextReturn = outputs.getNextReturn();
|
||||
ProcedureResult procedureResult = query.getResult();
|
||||
assertTrue( "Checking ProcedureResult has more returns", procedureResult.hasMoreReturns() );
|
||||
Return nextReturn = procedureResult.getNextReturn();
|
||||
assertNotNull( nextReturn );
|
||||
ExtraAssertions.assertClassAssignability( ResultSetReturn.class, nextReturn.getClass() );
|
||||
ResultSetReturn resultSetReturn = (ResultSetReturn) nextReturn;
|
||||
|
@ -304,12 +304,12 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
|||
// execution
|
||||
|
||||
{
|
||||
Call query = session.createStoredProcedureCall( "findUserRange" );
|
||||
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
|
||||
query.registerParameter( 1, Integer.class, ParameterMode.IN );
|
||||
query.registerParameter( 2, Integer.class, ParameterMode.IN ).bindValue( 2 );
|
||||
Outputs outputs = query.getOutputs();
|
||||
ProcedureResult procedureResult = query.getResult();
|
||||
try {
|
||||
outputs.hasMoreReturns();
|
||||
procedureResult.hasMoreReturns();
|
||||
fail( "Expecting failure due to missing parameter bind" );
|
||||
}
|
||||
catch (JDBCException expected) {
|
||||
|
@ -317,12 +317,12 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
|
||||
{
|
||||
Call query = session.createStoredProcedureCall( "findUserRange" );
|
||||
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
|
||||
query.registerParameter( "start", Integer.class, ParameterMode.IN );
|
||||
query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
|
||||
Outputs outputs = query.getOutputs();
|
||||
ProcedureResult procedureResult = query.getResult();
|
||||
try {
|
||||
outputs.hasMoreReturns();
|
||||
procedureResult.hasMoreReturns();
|
||||
fail( "Expecting failure due to missing parameter bind" );
|
||||
}
|
||||
catch (JDBCException expected) {
|
||||
|
|
|
@ -37,11 +37,11 @@ import java.util.List;
|
|||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.procedure.Call;
|
||||
import org.hibernate.procedure.Outputs;
|
||||
import org.hibernate.procedure.ResultSetReturn;
|
||||
import org.hibernate.procedure.Return;
|
||||
import org.hibernate.procedure.UpdateCountReturn;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.procedure.ProcedureResult;
|
||||
import org.hibernate.result.ResultSetReturn;
|
||||
import org.hibernate.result.Return;
|
||||
import org.hibernate.result.UpdateCountReturn;
|
||||
import org.hibernate.jpa.spi.BaseQueryImpl;
|
||||
import org.hibernate.jpa.spi.HibernateEntityManagerImplementor;
|
||||
|
||||
|
@ -49,10 +49,10 @@ import org.hibernate.jpa.spi.HibernateEntityManagerImplementor;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredProcedureQuery {
|
||||
private final Call procedureCall;
|
||||
private Outputs procedureOutputs;
|
||||
private final ProcedureCall procedureCall;
|
||||
private ProcedureResult procedureResult;
|
||||
|
||||
public StoredProcedureQueryImpl(Call procedureCall, HibernateEntityManagerImplementor entityManager) {
|
||||
public StoredProcedureQueryImpl(ProcedureCall procedureCall, HibernateEntityManagerImplementor entityManager) {
|
||||
super( entityManager );
|
||||
this.procedureCall = procedureCall;
|
||||
}
|
||||
|
@ -172,11 +172,11 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
|
||||
// outputs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
private Outputs outputs() {
|
||||
if ( procedureOutputs == null ) {
|
||||
procedureOutputs = procedureCall.getOutputs();
|
||||
private ProcedureResult outputs() {
|
||||
if ( procedureResult == null ) {
|
||||
procedureResult = procedureCall.getResult();
|
||||
}
|
||||
return procedureOutputs;
|
||||
return procedureResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -83,7 +83,7 @@ import org.hibernate.SQLQuery;
|
|||
import org.hibernate.Session;
|
||||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.StaleStateException;
|
||||
import org.hibernate.procedure.Call;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.TransientObjectException;
|
||||
import org.hibernate.TypeMismatchException;
|
||||
import org.hibernate.UnresolvableObjectException;
|
||||
|
@ -813,8 +813,8 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
@Override
|
||||
public StoredProcedureQuery createStoredProcedureQuery(String procedureName) {
|
||||
try {
|
||||
Call call = getSession().createStoredProcedureCall( procedureName );
|
||||
return new StoredProcedureQueryImpl( call, this );
|
||||
ProcedureCall procedureCall = getSession().createStoredProcedureCall( procedureName );
|
||||
return new StoredProcedureQueryImpl( procedureCall, this );
|
||||
}
|
||||
catch ( HibernateException he ) {
|
||||
throw convert( he );
|
||||
|
@ -824,8 +824,8 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
@Override
|
||||
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) {
|
||||
try {
|
||||
Call call = getSession().createStoredProcedureCall( procedureName, resultClasses );
|
||||
return new StoredProcedureQueryImpl( call, this );
|
||||
ProcedureCall procedureCall = getSession().createStoredProcedureCall( procedureName, resultClasses );
|
||||
return new StoredProcedureQueryImpl( procedureCall, this );
|
||||
}
|
||||
catch ( HibernateException he ) {
|
||||
throw convert( he );
|
||||
|
|
Loading…
Reference in New Issue