Merge pull request #185 from ghillert/INT-2241
Stored Proc: Add attribute: skipUndeclaredResults For reference see: https://jira.springsource.org/browse/INT-2241
This commit is contained in:
@@ -26,6 +26,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SqlInOutParameter;
|
||||
import org.springframework.jdbc.core.SqlOutParameter;
|
||||
@@ -65,7 +66,7 @@ public class StoredProcExecutor implements InitializingBean {
|
||||
/**
|
||||
* Uses the {@link SimpleJdbcCall} implementation for executing Stored Procedures.
|
||||
*/
|
||||
private final SimpleJdbcCallOperations jdbcCallOperations;
|
||||
private final SimpleJdbcCall jdbcCallOperations;
|
||||
|
||||
/**
|
||||
* Name of the stored procedure or function to be executed.
|
||||
@@ -81,6 +82,16 @@ public class StoredProcExecutor implements InitializingBean {
|
||||
*/
|
||||
private volatile boolean ignoreColumnMetaData = false;
|
||||
|
||||
/**
|
||||
* If this variable is set to true then all results from a stored procedure call
|
||||
* that don't have a corresponding SqlOutParameter declaration will be bypassed.
|
||||
*
|
||||
* The value is set on the underlying {@link JdbcTemplate}.
|
||||
*
|
||||
* Value defaults to <code>true</code>.
|
||||
*/
|
||||
private volatile boolean skipUndeclaredResults = true;
|
||||
|
||||
/**
|
||||
* If your database system is not fully supported by Spring and thus obtaining
|
||||
* parameter definitions from the JDBC Meta-data is not possible, you must define
|
||||
@@ -204,6 +215,8 @@ public class StoredProcExecutor implements InitializingBean {
|
||||
this.jdbcCallOperations.withProcedureName(this.storedProcedureName);
|
||||
}
|
||||
|
||||
this.jdbcCallOperations.getJdbcTemplate().setSkipUndeclaredResults(this.skipUndeclaredResults);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,19 +346,67 @@ public class StoredProcExecutor implements InitializingBean {
|
||||
return this.storedProcedureName;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to 'true', the payload of the Message will be used as a source for
|
||||
* providing parameters. If false the entire Message will be available as a
|
||||
* source for parameters.
|
||||
*
|
||||
* If no {@link ProcedureParameter} are passed in, this property will default to
|
||||
* 'true'. This means that using a default {@link BeanPropertySqlParameterSourceFactory}
|
||||
* the bean properties of the payload will be used as a source for parameter values for
|
||||
* the to-be-executed Stored Procedure or Function.
|
||||
*
|
||||
* However, if {@link ProcedureParameter} are passed in, then this property
|
||||
* will by default evaluate to 'false'. {@link ProcedureParameter} allow for
|
||||
* SpEl Expressions to be provided and therefore it is highly beneficial to
|
||||
* have access to the entire {@link Message}.
|
||||
*
|
||||
* @param usePayloadAsParameterSource If false the entire {@link Message} is used as parameter source.
|
||||
*/
|
||||
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
|
||||
this.usePayloadAsParameterSource = usePayloadAsParameterSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether a Stored Procedure or a Function is being executed.
|
||||
* The default value is false.
|
||||
*
|
||||
* @param isFunction If set to true an Sql Function is executed rather than a Stored Procedure.
|
||||
*/
|
||||
public void setFunction(boolean isFunction) {
|
||||
this.isFunction = isFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the procedure's return value should be included in the results
|
||||
* returned.
|
||||
*
|
||||
* @param returnValueRequired
|
||||
*/
|
||||
public void setReturnValueRequired(boolean returnValueRequired) {
|
||||
this.returnValueRequired = returnValueRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* If this variable is set to <code>true</code> then all results from a stored
|
||||
* procedure call that don't have a corresponding {@link SqlOutParameter}
|
||||
* declaration will be bypassed.
|
||||
*
|
||||
* E.g. Stored Procedures may return an update count value, even though your
|
||||
* Stored Procedure only declared a single result parameter. The exact behavior
|
||||
* depends on the used database.
|
||||
*
|
||||
* The value is set on the underlying {@link JdbcTemplate}.
|
||||
*
|
||||
* Only few developers will probably ever like to process update counts, thus
|
||||
* the value defaults to <code>true</code>.
|
||||
*
|
||||
*/
|
||||
public void setSkipUndeclaredResults(boolean skipUndeclaredResults) {
|
||||
this.skipUndeclaredResults = skipUndeclaredResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the Stored Procedure returns ResultSets you may provide a map of
|
||||
* {@link RowMapper} to convert the {@link ResultSet} to meaningful objects.
|
||||
*
|
||||
|
||||
@@ -21,9 +21,6 @@ import javax.sql.DataSource;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageDeliveryException;
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.integration.MessageRejectedException;
|
||||
import org.springframework.integration.handler.AbstractMessageHandler;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
@@ -35,33 +32,31 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* A message handler that executes Stored Procedures for update purposes.
|
||||
*
|
||||
* Stored procedure parameter value are by default automatically extracted from
|
||||
* the Payload if the payload's bean properties match the parameters of the Stored
|
||||
* Procedure.
|
||||
*
|
||||
* Stored procedure parameter values are by default automatically extracted from
|
||||
* the Payload if the payload's bean properties match the parameters of the Stored
|
||||
* Procedure.
|
||||
*
|
||||
* This may be sufficient for basic use cases. For more sophisticated options
|
||||
* consider passing in one or more {@link ProcedureParameter}.
|
||||
*
|
||||
* If you need to handle the return parameters of the called stored procedure
|
||||
* explicitly, please consider using a {@link StoredProcOutboundGateway} instead.
|
||||
*
|
||||
* Also, if you need to execute SQL Functions, please also use the
|
||||
* {@link StoredProcOutboundGateway}. As functions are typically used to look up
|
||||
* values, only, the Stored Procedure message handler does purposefully not support
|
||||
* SQL function calls. If you believe there are valid use-cases for that, please file a
|
||||
* Also, if you need to execute SQL Functions, please also use the
|
||||
* {@link StoredProcOutboundGateway}. As functions are typically used to look up
|
||||
* values, only, the Stored Procedure message handler purposefully does not support
|
||||
* SQL function calls. If you believe there are valid use-cases for that, please file a
|
||||
* feature request at http://jira.springsource.org.
|
||||
*
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public class StoredProcMessageHandler extends AbstractMessageHandler implements InitializingBean {
|
||||
|
||||
final StoredProcExecutor executor;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor taking {@link DataSource} from which the DB Connection can be
|
||||
* Constructor taking {@link DataSource} from which the DB Connection can be
|
||||
* obtained and the name of the stored procedure or function to
|
||||
* execute to retrieve new rows.
|
||||
*
|
||||
@@ -69,17 +64,17 @@ public class StoredProcMessageHandler extends AbstractMessageHandler implements
|
||||
* @param storedProcedureName The name of the Stored Procedure or Function. Must not be null.
|
||||
*/
|
||||
public StoredProcMessageHandler(DataSource dataSource, String storedProcedureName) {
|
||||
|
||||
|
||||
Assert.notNull(dataSource, "dataSource must not be null.");
|
||||
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
|
||||
|
||||
|
||||
this.executor = new StoredProcExecutor(dataSource, storedProcedureName);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies parameters, sets the parameters on {@link SimpleJdbcCallOperations}
|
||||
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
|
||||
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
|
||||
* when {@link ProcedureParameter} are passed in.
|
||||
*/
|
||||
@Override
|
||||
@@ -87,44 +82,43 @@ public class StoredProcMessageHandler extends AbstractMessageHandler implements
|
||||
super.onInit();
|
||||
this.executor.afterPropertiesSet();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Executes the Stored procedure, delegates to executeStoredProcedure(...).
|
||||
* Any return values from the Stored procedure are ignored.
|
||||
*
|
||||
* Return values are logged at debug level, though.
|
||||
* Any return values from the Stored procedure are ignored.
|
||||
*
|
||||
* Return values are logged at debug level, though.
|
||||
*/
|
||||
@Override
|
||||
protected void handleMessageInternal(Message<?> message) throws MessageRejectedException, MessageHandlingException,
|
||||
MessageDeliveryException {
|
||||
protected void handleMessageInternal(Message<?> message) {
|
||||
|
||||
Map<String, Object> resultMap = executor.executeStoredProcedure(message);
|
||||
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
|
||||
if (resultMap != null && !resultMap.isEmpty()) {
|
||||
logger.debug(String.format("The StoredProcMessageHandler ignores return "
|
||||
logger.debug(String.format("The StoredProcMessageHandler ignores return "
|
||||
+ "values, but the called Stored Procedure '%s' returned the "
|
||||
+ "following data: '%s'", executor.getStoredProcedureName(), resultMap));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//~~~~~Setters for Properties~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
/**
|
||||
* For fully supported databases, the underlying {@link SimpleJdbcCall} can
|
||||
* retrieve the parameter information for the to be invoked Stored Procedure
|
||||
* from the JDBC Meta-data. However, if the used database does not support
|
||||
* retrieve the parameter information for the to be invoked Stored Procedure
|
||||
* from the JDBC Meta-data. However, if the used database does not support
|
||||
* meta data lookups or if you like to provide customized parameter definitions,
|
||||
* this flag can be set to 'true'. It defaults to 'false'.
|
||||
* this flag can be set to <code>true</code>. It defaults to <code>false</code>.
|
||||
*/
|
||||
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
|
||||
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom Stored Procedure parameters that may contain static values
|
||||
* or Strings representing an {@link Expression}.
|
||||
@@ -132,25 +126,25 @@ public class StoredProcMessageHandler extends AbstractMessageHandler implements
|
||||
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
|
||||
this.executor.setProcedureParameters(procedureParameters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If you database system is not fully supported by Spring and thus obtaining
|
||||
* If your database system is not fully supported by Spring and thus obtaining
|
||||
* parameter definitions from the JDBC Meta-data is not possible, you must define
|
||||
* the {@link SqlParameter} explicitly.
|
||||
* the {@link SqlParameter} explicitly.
|
||||
*/
|
||||
public void setSqlParameters(List<SqlParameter> sqlParameters) {
|
||||
this.executor.setSqlParameters(sqlParameters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides the ability to set a custom {@link SqlParameterSourceFactory}.
|
||||
* Keep in mind that if {@link ProcedureParameter} are set explicitly and
|
||||
* you would like to provide a custom {@link SqlParameterSourceFactory},
|
||||
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
|
||||
*
|
||||
* If not the SqlParameterSourceFactory will be replaced the default
|
||||
* Provides the ability to set a custom {@link SqlParameterSourceFactory}.
|
||||
* Keep in mind that if {@link ProcedureParameter} are set explicitly and
|
||||
* you would like to provide a custom {@link SqlParameterSourceFactory},
|
||||
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
|
||||
*
|
||||
* If not the SqlParameterSourceFactory will be replaced by the default
|
||||
* {@link ExpressionEvaluatingSqlParameterSourceFactory}.
|
||||
*
|
||||
*
|
||||
* @param sqlParameterSourceFactory
|
||||
*/
|
||||
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
|
||||
@@ -158,24 +152,24 @@ public class StoredProcMessageHandler extends AbstractMessageHandler implements
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to 'true', the payload of the Message will be used as a source for
|
||||
* providing parameters. If false the entire Message will be available as a
|
||||
* source for parameters.
|
||||
*
|
||||
* If set to 'true', the payload of the Message will be used as a source for
|
||||
* providing parameters. If false the entire Message will be available as a
|
||||
* source for parameters.
|
||||
*
|
||||
* If no {@link ProcedureParameter} are passed in, this property will default to
|
||||
* 'true'. This means that using a default {@link BeanPropertySqlParameterSourceFactory}
|
||||
* the bean properties of the payload will be used as a source for parameter values for
|
||||
* the bean properties of the payload will be used as a source for parameter values for
|
||||
* the to-be-executed Stored Procedure or Function.
|
||||
*
|
||||
* However, if {@link ProcedureParameter} are passed in, then this property
|
||||
* will by default evaluate to 'false'. {@link ProcedureParameter} allow for
|
||||
*
|
||||
* However, if {@link ProcedureParameter} are passed in, then this property
|
||||
* will by default evaluate to 'false'. {@link ProcedureParameter} allow for
|
||||
* SpEl Expressions to be provided and therefore it is highly beneficial to
|
||||
* have access to the entire {@link Message}.
|
||||
*
|
||||
* @param usePayloadAsParameterSource If false the entire {@link Message} is used as parameter source.
|
||||
*
|
||||
* @param usePayloadAsParameterSource If false the entire {@link Message} is used as parameter source.
|
||||
*/
|
||||
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
|
||||
this.executor.setUsePayloadAsParameterSource(usePayloadAsParameterSource);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,13 +21,16 @@ import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SqlOutParameter;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcCallOperations;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
@@ -43,27 +46,27 @@ public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHand
|
||||
private final StoredProcExecutor executor;
|
||||
|
||||
private volatile boolean expectSingleResult = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor taking {@link DataSource} from which the DB Connection can be
|
||||
* Constructor taking {@link DataSource} from which the DB Connection can be
|
||||
* obtained and the name of the stored procedure or function to
|
||||
* execute to retrieve new rows.
|
||||
*
|
||||
* @param dataSource used to create a {@link SimpleJdbcTemplate}
|
||||
* @param storedProcedureName
|
||||
* @param storedProcedureName
|
||||
*/
|
||||
public StoredProcOutboundGateway(DataSource dataSource, String storedProcedureName) {
|
||||
|
||||
|
||||
Assert.notNull(dataSource, "dataSource must not be null.");
|
||||
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
|
||||
|
||||
|
||||
this.executor = new StoredProcExecutor(dataSource, storedProcedureName);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies parameters, sets the parameters on {@link SimpleJdbcCallOperations}
|
||||
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
|
||||
* and ensures the appropriate {@link SqlParameterSourceFactory} is defined
|
||||
* when {@link ProcedureParameter} are passed in.
|
||||
*/
|
||||
@Override
|
||||
@@ -74,19 +77,19 @@ public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHand
|
||||
|
||||
@Override
|
||||
protected Object handleRequestMessage(Message<?> requestMessage) {
|
||||
|
||||
|
||||
Map<String, Object> resultMap = executor.executeStoredProcedure(requestMessage);
|
||||
|
||||
|
||||
final Object payload;
|
||||
|
||||
|
||||
if (resultMap.isEmpty()) {
|
||||
payload = null;
|
||||
} else {
|
||||
|
||||
|
||||
if (this.expectSingleResult && resultMap.size() == 1) {
|
||||
payload = resultMap.values().iterator().next();
|
||||
} else if (this.expectSingleResult && resultMap.size() > 1) {
|
||||
|
||||
|
||||
throw new MessageHandlingException(requestMessage,
|
||||
"Stored Procedure/Function call returned more than "
|
||||
+ "1 result object and expectSingleResult was 'true'. ");
|
||||
@@ -94,11 +97,11 @@ public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHand
|
||||
} else {
|
||||
payload = resultMap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return MessageBuilder.withPayload(payload).copyHeaders(requestMessage.getHeaders()).build();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,80 +145,121 @@ public class StoredProcOutboundGateway extends AbstractReplyProducingMessageHand
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, the JDBC parameter definitions for the stored procedure are not
|
||||
* automatically derived from the underlying JDBC connection. In that case
|
||||
* you must pass in {@link SqlParameter} explicitly..
|
||||
*
|
||||
* @param ignoreColumnMetaData
|
||||
* @param ignoreColumnMetaData Defaults to <code>false</code>.
|
||||
*/
|
||||
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
|
||||
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the procedure's return value should be included in the results
|
||||
* returned.
|
||||
*
|
||||
* @param returnValueRequired
|
||||
*/
|
||||
public void setReturnValueRequired(boolean returnValueRequired) {
|
||||
this.executor.setReturnValueRequired(returnValueRequired);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom Stored Procedure parameters that may contain static values
|
||||
* or Strings representing an {@link Expression}.
|
||||
*/
|
||||
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
|
||||
this.executor.setProcedureParameters(procedureParameters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether a Stored Procedure or a Function is being executed.
|
||||
* The default value is false.
|
||||
*
|
||||
* @param isFunction If set to true an Sql Function is executed rather than a Stored Procedure.
|
||||
*/
|
||||
public void setIsFunction(boolean isFunction) {
|
||||
this.executor.setFunction(isFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* This parameter indicates that only one result object shall be returned from
|
||||
* the Stored Procedure/Function Call. If set to true, a resultMap that contains
|
||||
* the Stored Procedure/Function Call. If set to true, a resultMap that contains
|
||||
* only 1 element, will have that 1 element extracted and returned as payload.
|
||||
*
|
||||
* If the resultMap contains more than 1 element and expectSingleResult is true,
|
||||
* then a {@link MessagingException} is thrown.
|
||||
*
|
||||
*
|
||||
* If the resultMap contains more than 1 element and expectSingleResult is true,
|
||||
* then a {@link MessagingException} is thrown.
|
||||
*
|
||||
* Otherwise the complete resultMap is returned as the {@link Message} payload.
|
||||
*
|
||||
* Important Note: Several databases such as H2 are not fully supported.
|
||||
* The H2 database, for example, does not fully support the {@link CallableStatement}
|
||||
* semantics and when executing function calls against H2, a result list is
|
||||
* returned rather than a single value.
|
||||
*
|
||||
* Therefore, even if you set expectSingleResult = true, you may end up with
|
||||
*
|
||||
* Important Note: Several databases such as H2 are not fully supported.
|
||||
* The H2 database, for example, does not fully support the {@link CallableStatement}
|
||||
* semantics and when executing function calls against H2, a result list is
|
||||
* returned rather than a single value.
|
||||
*
|
||||
* Therefore, even if you set expectSingleResult = true, you may end up with
|
||||
* a collection being returned.
|
||||
*
|
||||
*
|
||||
* @param expectSingleResult
|
||||
*/
|
||||
public void setExpectSingleResult(boolean expectSingleResult) {
|
||||
this.expectSingleResult = expectSingleResult;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sqlParameterSourceFactory
|
||||
*/
|
||||
/**
|
||||
* Provides the ability to set a custom {@link SqlParameterSourceFactory}.
|
||||
* Keep in mind that if {@link ProcedureParameter} are set explicitly and
|
||||
* you would like to provide a custom {@link SqlParameterSourceFactory},
|
||||
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
|
||||
*
|
||||
* If not the SqlParameterSourceFactory will be replaced by the default
|
||||
* {@link ExpressionEvaluatingSqlParameterSourceFactory}.
|
||||
*
|
||||
* @param sqlParameterSourceFactory
|
||||
*/
|
||||
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
|
||||
this.executor.setSqlParameterSourceFactory(sqlParameterSourceFactory);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If set to 'true', the payload of the Message will be used as a source for
|
||||
* providing parameters. If false the entire Message will be available as a
|
||||
* source for parameters.
|
||||
*
|
||||
* If set to 'true', the payload of the Message will be used as a source for
|
||||
* providing parameters. If false the entire Message will be available as a
|
||||
* source for parameters.
|
||||
*
|
||||
* If no {@link ProcedureParameter} are passed in, this property will default to
|
||||
* 'true'. This means that using a default {@link BeanPropertySqlParameterSourceFactory}
|
||||
* the bean properties of the payload will be used as a source for parameter values for
|
||||
* the bean properties of the payload will be used as a source for parameter values for
|
||||
* the to-be-executed Stored Procedure or Function.
|
||||
*
|
||||
* However, if {@link ProcedureParameter} are passed in, then this property
|
||||
* will by default evaluate to 'false'. {@link ProcedureParameter} allow for
|
||||
*
|
||||
* However, if {@link ProcedureParameter} are passed in, then this property
|
||||
* will by default evaluate to 'false'. {@link ProcedureParameter} allow for
|
||||
* SpEl Expressions to be provided and therefore it is highly beneficial to
|
||||
* have access to the entire {@link Message}.
|
||||
*
|
||||
* @param usePayloadAsParameterSource If false the entire {@link Message} is used as parameter source.
|
||||
*
|
||||
* @param usePayloadAsParameterSource If false the entire {@link Message} is used as parameter source.
|
||||
*/
|
||||
public void setUsePayloadAsParameterSource(boolean usePayloadAsParameterSource) {
|
||||
this.executor.setUsePayloadAsParameterSource(usePayloadAsParameterSource);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If this variable is set to <code>true</code> then all results from a stored
|
||||
* procedure call that don't have a corresponding {@link SqlOutParameter}
|
||||
* declaration will be bypassed.
|
||||
*
|
||||
* E.g. Stored Procedures may return an update count value, even though your
|
||||
* Stored Procedure only declared a single result parameter. The exact behavior
|
||||
* depends on the used database.
|
||||
*
|
||||
* The value is set on the underlying {@link JdbcTemplate}.
|
||||
*
|
||||
* Only few developers will probably ever like to process update counts, thus
|
||||
* the value defaults to <code>true</code>.
|
||||
*
|
||||
*/
|
||||
public void setSkipUndeclaredResults(boolean skipUndeclaredResults) {
|
||||
this.executor.setSkipUndeclaredResults(skipUndeclaredResults);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,21 +21,24 @@ import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.context.IntegrationObjectSupport;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SqlOutParameter;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A polling channel adapter that creates messages from the payload returned by
|
||||
* executing a stored procedure or Sql function. Optionally an update can be executed
|
||||
* after the execution of the Stored Procedure or Function in order to update
|
||||
* executing a stored procedure or Sql function. Optionally an update can be executed
|
||||
* after the execution of the Stored Procedure or Function in order to update
|
||||
* processed rows.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
@@ -46,7 +49,7 @@ public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport im
|
||||
private final StoredProcExecutor executor;
|
||||
|
||||
private volatile boolean expectSingleResult = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor taking {@link DataSource} from which the DB Connection can be
|
||||
* obtained and the stored procedure name to execute.
|
||||
@@ -55,10 +58,10 @@ public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport im
|
||||
* @param storedProcedureName Name of the Stored Procedure or Function to execute
|
||||
*/
|
||||
public StoredProcPollingChannelAdapter(DataSource dataSource, String storedProcedureName) {
|
||||
|
||||
|
||||
Assert.notNull(dataSource, "dataSource must not be null.");
|
||||
Assert.hasText(storedProcedureName, "storedProcedureName must not be null and cannot be empty.");
|
||||
|
||||
|
||||
this.executor = new StoredProcExecutor(dataSource, storedProcedureName);
|
||||
|
||||
}
|
||||
@@ -97,11 +100,11 @@ public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport im
|
||||
if (resultMap.isEmpty()) {
|
||||
payload = null;
|
||||
} else {
|
||||
|
||||
|
||||
if (this.expectSingleResult && resultMap.size() == 1) {
|
||||
payload = resultMap.values().iterator().next();
|
||||
} else if (this.expectSingleResult && resultMap.size() > 1) {
|
||||
|
||||
|
||||
throw new MessagingException(
|
||||
"Stored Procedure/Function call returned more than "
|
||||
+ "1 result object and expectSingleResult was 'true'. ");
|
||||
@@ -109,11 +112,11 @@ public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport im
|
||||
} else {
|
||||
payload = resultMap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return payload;
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected Map<String, ?> doPoll() {
|
||||
@@ -124,10 +127,17 @@ public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport im
|
||||
return "stored-proc:inbound-channel-adapter";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sqlParameterSourceFactory
|
||||
*/
|
||||
/**
|
||||
* Provides the ability to set a custom {@link SqlParameterSourceFactory}.
|
||||
* Keep in mind that if {@link ProcedureParameter} are set explicitly and
|
||||
* you would like to provide a custom {@link SqlParameterSourceFactory},
|
||||
* then you must provide an instance of {@link ExpressionEvaluatingSqlParameterSourceFactory}.
|
||||
*
|
||||
* If not the SqlParameterSourceFactory will be replaced by the default
|
||||
* {@link ExpressionEvaluatingSqlParameterSourceFactory}.
|
||||
*
|
||||
* @param sqlParameterSourceFactory
|
||||
*/
|
||||
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
|
||||
this.executor.setSqlParameterSourceFactory(sqlParameterSourceFactory);
|
||||
}
|
||||
@@ -173,30 +183,39 @@ public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport im
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, the JDBC parameter definitions for the stored procedure are not
|
||||
* automatically derived from the underlying JDBC connection. In that case
|
||||
* you must pass in {@link SqlParameter} explicitly..
|
||||
*
|
||||
* @param ignoreColumnMetaData
|
||||
* @param ignoreColumnMetaData Defaults to <code>false</code>.
|
||||
*/
|
||||
public void setIgnoreColumnMetaData(boolean ignoreColumnMetaData) {
|
||||
this.executor.setIgnoreColumnMetaData(ignoreColumnMetaData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the procedure's return value should be included in the results
|
||||
* returned.
|
||||
*
|
||||
* @param returnValueRequired
|
||||
*/
|
||||
public void setReturnValueRequired(boolean returnValueRequired) {
|
||||
this.executor.setReturnValueRequired(returnValueRequired);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom Stored Procedure parameters that may contain static values
|
||||
* or Strings representing an {@link Expression}.
|
||||
*/
|
||||
public void setProcedureParameters(List<ProcedureParameter> procedureParameters) {
|
||||
this.executor.setProcedureParameters(procedureParameters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether a Stored Procedure or a Function is being executed.
|
||||
* The default value is false.
|
||||
*
|
||||
* @param isFunction If set to true an Sql Function is executed rather than a Stored Procedure.
|
||||
* Indicates whether a Stored Procedure or a Function is being executed.
|
||||
* The default value is false.
|
||||
*
|
||||
* @param isFunction If set to true an Sql Function is executed rather than a Stored Procedure.
|
||||
*/
|
||||
public void setFunction(boolean isFunction) {
|
||||
this.executor.setFunction(isFunction);
|
||||
@@ -204,26 +223,45 @@ public class StoredProcPollingChannelAdapter extends IntegrationObjectSupport im
|
||||
|
||||
/**
|
||||
* This parameter indicates that only one result object shall be returned from
|
||||
* the Stored Procedure/Function Call. If set to true, a resultMap that contains
|
||||
* the Stored Procedure/Function Call. If set to true, a resultMap that contains
|
||||
* only 1 element, will have that 1 element extracted and returned as payload.
|
||||
*
|
||||
* If the resultMap contains more than 1 element and expectSingleResult is true,
|
||||
* then a {@link MessagingException} is thrown.
|
||||
*
|
||||
*
|
||||
* If the resultMap contains more than 1 element and expectSingleResult is true,
|
||||
* then a {@link MessagingException} is thrown.
|
||||
*
|
||||
* Otherwise the complete resultMap is returned as the {@link Message} payload.
|
||||
*
|
||||
* Important Note: Several databases such as H2 are not fully supported.
|
||||
* The H2 database, for example, does not fully support the {@link CallableStatement}
|
||||
* semantics and when executing function calls against H2, a result list is
|
||||
* returned rather than a single value.
|
||||
*
|
||||
* Therefore, even if you set expectSingleResult = true, you may end up with
|
||||
*
|
||||
* Important Note: Several databases such as H2 are not fully supported.
|
||||
* The H2 database, for example, does not fully support the {@link CallableStatement}
|
||||
* semantics and when executing function calls against H2, a result list is
|
||||
* returned rather than a single value.
|
||||
*
|
||||
* Therefore, even if you set expectSingleResult = true, you may end up with
|
||||
* a collection being returned.
|
||||
*
|
||||
*
|
||||
* @param expectSingleResult
|
||||
*/
|
||||
public void setExpectSingleResult(boolean expectSingleResult) {
|
||||
this.expectSingleResult = expectSingleResult;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If this variable is set to <code>true</code> then all results from a stored
|
||||
* procedure call that don't have a corresponding {@link SqlOutParameter}
|
||||
* declaration will be bypassed.
|
||||
*
|
||||
* E.g. Stored Procedures may return an update count value, even though your
|
||||
* Stored Procedure only declared a single result parameter. The exact behavior
|
||||
* depends on the used database.
|
||||
*
|
||||
* The value is set on the underlying {@link JdbcTemplate}.
|
||||
*
|
||||
* Only few developers will probably ever like to process update counts, thus
|
||||
* the value defaults to <code>true</code>.
|
||||
*
|
||||
*/
|
||||
public void setSkipUndeclaredResults(boolean skipUndeclaredResults) {
|
||||
this.executor.setSkipUndeclaredResults(skipUndeclaredResults);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
@@ -26,7 +26,7 @@ import org.w3c.dom.Element;
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class StoredProcMessageHandlerParser extends AbstractOutboundChannelAdapterParser {
|
||||
|
||||
@@ -43,30 +43,30 @@ public class StoredProcMessageHandlerParser extends AbstractOutboundChannelAdapt
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(StoredProcMessageHandler.class);
|
||||
|
||||
|
||||
String dataSourceRef = element.getAttribute("data-source");
|
||||
String storedProcedureName = element.getAttribute("stored-procedure-name");
|
||||
|
||||
|
||||
builder.addConstructorArgReference(dataSourceRef);
|
||||
builder.addConstructorArgValue(storedProcedureName);
|
||||
|
||||
builder.addConstructorArgValue(storedProcedureName);
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-column-meta-data");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "use-payload-as-parameter-source");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "sql-parameter-source-factory");
|
||||
|
||||
|
||||
final ManagedList<BeanDefinition> procedureParameterList = StoredProcParserUtils.getProcedureParameterBeanDefinitions(element, parserContext);
|
||||
final ManagedList<BeanDefinition> sqlParameterDefinitionList = StoredProcParserUtils.getSqlParameterDefinitionBeanDefinitions(element, parserContext);
|
||||
|
||||
if (!procedureParameterList.isEmpty()) {
|
||||
builder.addPropertyValue("procedureParameters", procedureParameterList);
|
||||
}
|
||||
|
||||
|
||||
if (!sqlParameterDefinitionList.isEmpty()) {
|
||||
builder.addPropertyValue("sqlParameters", sqlParameterDefinitionList);
|
||||
}
|
||||
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
@@ -27,10 +27,10 @@ import org.w3c.dom.Element;
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class StoredProcOutboundGatewayParser extends AbstractConsumerEndpointParser {
|
||||
|
||||
|
||||
protected boolean shouldGenerateId() {
|
||||
return false;
|
||||
}
|
||||
@@ -47,18 +47,18 @@ public class StoredProcOutboundGatewayParser extends AbstractConsumerEndpointPar
|
||||
|
||||
String dataSourceRef = gatewayElement.getAttribute("data-source");
|
||||
String storedProcedureName = gatewayElement.getAttribute("stored-procedure-name");
|
||||
|
||||
|
||||
builder.addConstructorArgReference(dataSourceRef);
|
||||
builder.addConstructorArgValue(storedProcedureName);
|
||||
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "is-function");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "ignore-column-meta-data");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "expect-single-result");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "return-value-required");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "use-payload-as-parameter-source");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, gatewayElement, "sql-parameter-source-factory");
|
||||
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, gatewayElement, "skip-undeclared-results");
|
||||
|
||||
final ManagedList<BeanDefinition> procedureParameterList = StoredProcParserUtils.getProcedureParameterBeanDefinitions(gatewayElement, parserContext);
|
||||
final ManagedList<BeanDefinition> sqlParameterDefinitionList = StoredProcParserUtils.getSqlParameterDefinitionBeanDefinitions(gatewayElement, parserContext);
|
||||
final ManagedMap<String, BeanDefinition> returningResultsetMap = StoredProcParserUtils.getReturningResultsetBeanDefinitions(gatewayElement, parserContext);
|
||||
@@ -85,5 +85,5 @@ public class StoredProcOutboundGatewayParser extends AbstractConsumerEndpointPar
|
||||
protected String getInputChannelAttributeName() {
|
||||
return "request-channel";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
@@ -27,10 +27,10 @@ import org.w3c.dom.Element;
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
* @since 2.1
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class StoredProcPollingChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
|
||||
|
||||
|
||||
protected boolean shouldGenerateId() {
|
||||
return false;
|
||||
}
|
||||
@@ -41,20 +41,21 @@ public class StoredProcPollingChannelAdapterParser extends AbstractPollingInboun
|
||||
|
||||
@Override
|
||||
protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) {
|
||||
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(StoredProcPollingChannelAdapter.class);
|
||||
|
||||
|
||||
String dataSourceRef = element.getAttribute("data-source");
|
||||
String storedProcedureName = element.getAttribute("stored-procedure-name");
|
||||
|
||||
|
||||
builder.addConstructorArgReference(dataSourceRef);
|
||||
builder.addConstructorArgValue(storedProcedureName);
|
||||
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-column-meta-data");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "return-value-required");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expect-single-result");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "function");
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "skip-undeclared-results");
|
||||
|
||||
final ManagedList<BeanDefinition> procedureParameterList = StoredProcParserUtils.getProcedureParameterBeanDefinitions(element, parserContext);
|
||||
final ManagedList<BeanDefinition> sqlParameterDefinitionList = StoredProcParserUtils.getSqlParameterDefinitionBeanDefinitions(element, parserContext);
|
||||
final ManagedMap<String, BeanDefinition> returningResultsetMap = StoredProcParserUtils.getReturningResultsetBeanDefinitions(element, parserContext);
|
||||
@@ -68,9 +69,9 @@ public class StoredProcPollingChannelAdapterParser extends AbstractPollingInboun
|
||||
if (!returningResultsetMap.isEmpty()) {
|
||||
builder.addPropertyValue("returningResultSetRowMappers", returningResultsetMap);
|
||||
}
|
||||
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a SqlParameterSourceFactory. The input is the whole
|
||||
Reference to a SqlParameterSourceFactory. The input is the whole
|
||||
outgoing message. The
|
||||
default factory creates a bean
|
||||
property parameter source so the query can specify named
|
||||
@@ -325,7 +325,7 @@
|
||||
supplied here, or (if keys-generated="true") can be the
|
||||
primary keys generated from an auto-increment, or else just a
|
||||
count of the number of rows affected by the update. The response
|
||||
is in general a case insensitive Map (or list of maps if multi-valued), unless
|
||||
is in general a case insensitive Map (or list of maps if multi-valued), unless
|
||||
a select query and a row-mapper is provided. If the update count is
|
||||
returned then the map key is "UPDATE".
|
||||
</xsd:documentation>
|
||||
@@ -365,7 +365,7 @@
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a SqlParameterSourceFactory. The input is the whole
|
||||
Reference to a SqlParameterSourceFactory. The input is the whole
|
||||
outgoing message. The
|
||||
default factory creates a bean
|
||||
property parameter source so the query can specify named
|
||||
@@ -381,7 +381,7 @@
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a SqlParameterSourceFactory. The input is the whole
|
||||
Reference to a SqlParameterSourceFactory. The input is the whole
|
||||
outgoing message. The
|
||||
default factory creates a bean
|
||||
property parameter source so the query can specify named
|
||||
@@ -568,12 +568,12 @@
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
For fully supported database these parameters
|
||||
need not be declared as for those database the
|
||||
type information can be retrieved from the
|
||||
JDBC Metadata.
|
||||
|
||||
need not be declared as for those database the
|
||||
type information can be retrieved from the
|
||||
JDBC Metadata.
|
||||
|
||||
Fully Supported Databases (Stored Procedures):
|
||||
|
||||
|
||||
* Apache Derby
|
||||
* DB2
|
||||
* MySQL
|
||||
@@ -581,16 +581,16 @@
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
* Sybase
|
||||
|
||||
|
||||
Fully Supported Databases (Functions)
|
||||
|
||||
|
||||
* MySQL
|
||||
* Microsoft SQL Server
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
|
||||
|
||||
If you use a database not listed above, you
|
||||
MUST provide Sql Parameter Definitions.
|
||||
MUST provide Sql Parameter Definitions.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -613,21 +613,21 @@
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
If set to 'true', the payload of the Message will be used
|
||||
as a source for providing parameters. If false the entire
|
||||
Message will be available as a source for parameters.
|
||||
|
||||
If no Procedure Parameters are passed in, this property
|
||||
will default to 'true'. This means that using a default
|
||||
BeanPropertySqlParameterSourceFactory the bean properties
|
||||
of the payload will be used as a source for parameter
|
||||
If set to 'true', the payload of the Message will be used
|
||||
as a source for providing parameters. If false the entire
|
||||
Message will be available as a source for parameters.
|
||||
|
||||
If no Procedure Parameters are passed in, this property
|
||||
will default to 'true'. This means that using a default
|
||||
BeanPropertySqlParameterSourceFactory the bean properties
|
||||
of the payload will be used as a source for parameter
|
||||
values for the to-be-executed Stored Procedure or Function.
|
||||
|
||||
However, if Procedure Parameters are passed in, then this
|
||||
property will by default evaluate to 'false'. ProcedureParameter
|
||||
allow for SpEl Expressions to be provided and therefore
|
||||
it is highly beneficial to have access to the entire Message.
|
||||
]]>
|
||||
|
||||
However, if Procedure Parameters are passed in, then this
|
||||
property will by default evaluate to 'false'. ProcedureParameter
|
||||
allow for SpEl Expressions to be provided and therefore
|
||||
it is highly beneficial to have access to the entire Message.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -704,12 +704,12 @@
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
For fully supported database these parameters
|
||||
generally need not be declared as for those
|
||||
databases the type information can be
|
||||
retrieved from the JDBC Metadata.
|
||||
|
||||
generally need not be declared as for those
|
||||
databases the type information can be
|
||||
retrieved from the JDBC Metadata.
|
||||
|
||||
Fully Supported Databases (Stored Procedures):
|
||||
|
||||
|
||||
* Apache Derby
|
||||
* DB2
|
||||
* MySQL
|
||||
@@ -717,27 +717,27 @@
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
* Sybase
|
||||
|
||||
|
||||
Fully Supported Databases (Functions)
|
||||
|
||||
|
||||
* MySQL
|
||||
* Microsoft SQL Server
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
|
||||
|
||||
If you use a database not listed above, you
|
||||
MUST provide Sql Parameter Definitions.
|
||||
MUST provide Sql Parameter Definitions.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:element>
|
||||
<xsd:element name="parameter" minOccurs="0" maxOccurs="unbounded"
|
||||
type="parameterSubElementType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Provides a mechanism to provide stored procedure
|
||||
parameters. Parameters can be either static
|
||||
parameters. Parameters can be either static
|
||||
or provided using a SpEL Expression.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
@@ -748,7 +748,7 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Storeed procedured may return multiple resultsets.
|
||||
Stored procedures may return multiple resultsets.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -761,28 +761,28 @@
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
If set to 'true', the payload of the Message will be used
|
||||
as a source for providing parameters. If false the entire
|
||||
Message will be available as a source for parameters.
|
||||
|
||||
If no Procedure Parameters are passed in, this property
|
||||
will default to 'true'. This means that using a default
|
||||
BeanPropertySqlParameterSourceFactory the bean properties
|
||||
of the payload will be used as a source for parameter
|
||||
If set to 'true', the payload of the Message will be used
|
||||
as a source for providing parameters. If false the entire
|
||||
Message will be available as a source for parameters.
|
||||
|
||||
If no Procedure Parameters are passed in, this property
|
||||
will default to 'true'. This means that using a default
|
||||
BeanPropertySqlParameterSourceFactory the bean properties
|
||||
of the payload will be used as a source for parameter
|
||||
values for the to-be-executed Stored Procedure or Function.
|
||||
|
||||
However, if Procedure Parameters are passed in, then this
|
||||
property will by default evaluate to 'false'. ProcedureParameter
|
||||
allow for SpEl Expressions to be provided and therefore
|
||||
it is highly beneficial to have access to the entire Message.
|
||||
]]>
|
||||
|
||||
However, if Procedure Parameters are passed in, then this
|
||||
property will by default evaluate to 'false'. ProcedureParameter
|
||||
allow for SpEl Expressions to be provided and therefore
|
||||
it is highly beneficial to have access to the entire Message.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="sql-parameter-source-factory"
|
||||
type="xsd:string">
|
||||
<xsd:annotation>
|
||||
@@ -800,7 +800,7 @@
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="is-function" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
@@ -813,29 +813,51 @@
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="skip-undeclared-results" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
If this attribute is set to 'true', then all results from
|
||||
a stored procedure call that don't have a corresponding
|
||||
'SqlOutParameter' declaration will be bypassed.
|
||||
|
||||
E.g. Stored Procedures may return an update count value,
|
||||
even though your Stored Procedure only declared a single
|
||||
result parameter. The exact behavior depends on the used
|
||||
database.
|
||||
|
||||
The value is set on the underlying 'JdbcTemplate'.
|
||||
|
||||
Only few developers will probably ever like to process
|
||||
update counts, thus the value defaults to 'true'.]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expect-single-result" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This parameter indicates that only one result object shall be returned from
|
||||
the Stored Procedure/Function Call. If set to true and the result map
|
||||
the Stored Procedure/Function Call. If set to true and the result map
|
||||
from the Stored Procedure/Function Call contains only 1 element,
|
||||
then that 1 element is extracted and returned as payload.
|
||||
|
||||
If the result map contains more than 1 element and
|
||||
expect-single-result is true, then a MessagingException
|
||||
is thrown.
|
||||
|
||||
Otherwise the complete result map is returned as the
|
||||
|
||||
If the result map contains more than 1 element and
|
||||
expect-single-result is true, then a MessagingException
|
||||
is thrown.
|
||||
|
||||
Otherwise the complete result map is returned as the
|
||||
payload.
|
||||
|
||||
Important Note: Several databases such as H2 are not
|
||||
fully supported for Stored Procedure and/oir Function calls.
|
||||
|
||||
|
||||
Important Note: Several databases such as H2 are not
|
||||
fully supported for Stored Procedure and/oir Function calls.
|
||||
|
||||
The H2 database, for example, does not fully support the CallableStatement
|
||||
semantics and when executing function calls against H2, a result list is
|
||||
returned, rather than a single value.
|
||||
|
||||
Therefore, even if you set expect-single-result = true,
|
||||
semantics and when executing function calls against H2, a result list is
|
||||
returned, rather than a single value.
|
||||
|
||||
Therefore, even if you set expect-single-result = true,
|
||||
you may end up with a collection being returned.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
@@ -843,7 +865,7 @@
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="request-channel" type="xsd:string"
|
||||
use="required">
|
||||
<xsd:annotation>
|
||||
@@ -877,8 +899,8 @@
|
||||
<xsd:attribute name="return-value-required" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Indicates whether this procedure's return value
|
||||
should be included.
|
||||
Indicates the procedure's return value should be included
|
||||
in the results returned.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
@@ -905,12 +927,12 @@
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
For fully supported database these parameters
|
||||
need not be declared as for those database the
|
||||
type information can be retrieved from the
|
||||
JDBC Metadata.
|
||||
|
||||
need not be declared as for those database the
|
||||
type information can be retrieved from the
|
||||
JDBC Metadata.
|
||||
|
||||
Fully Supported Databases (Stored Procedures):
|
||||
|
||||
|
||||
* Apache Derby
|
||||
* DB2
|
||||
* MySQL
|
||||
@@ -918,20 +940,20 @@
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
* Sybase
|
||||
|
||||
|
||||
Fully Supported Databases (Functions)
|
||||
|
||||
|
||||
* MySQL
|
||||
* Microsoft SQL Server
|
||||
* Oracle
|
||||
* PostgreSQL
|
||||
|
||||
|
||||
If you use a database not listed above, you
|
||||
MUST provide Sql Parameter Definitions.
|
||||
MUST provide Sql Parameter Definitions.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:element>
|
||||
<xsd:element name="parameter" minOccurs="0" maxOccurs="unbounded"
|
||||
type="parameterSubElementType">
|
||||
<xsd:annotation>
|
||||
@@ -967,29 +989,51 @@
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="skip-undeclared-results" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
If this attribute is set to 'true', then all results from
|
||||
a stored procedure call that don't have a corresponding
|
||||
'SqlOutParameter' declaration will be bypassed.
|
||||
|
||||
E.g. Stored Procedures may return an update count value,
|
||||
even though your Stored Procedure only declared a single
|
||||
result parameter. The exact behavior depends on the used
|
||||
database.
|
||||
|
||||
The value is set on the underlying 'JdbcTemplate'.
|
||||
|
||||
Only few developers will probably ever like to process
|
||||
update counts, thus the value defaults to 'true'.]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expect-single-result" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This parameter indicates that only one result object shall be returned from
|
||||
the Stored Procedure/Function Call. If set to true and the result map
|
||||
the Stored Procedure/Function Call. If set to true and the result map
|
||||
from the Stored Procedure/Function Call contains only 1 element,
|
||||
then that 1 element is extracted and returned as payload.
|
||||
|
||||
If the result map contains more than 1 element and
|
||||
expect-single-result is true, then a MessagingException
|
||||
is thrown.
|
||||
|
||||
Otherwise the complete result map is returned as the
|
||||
|
||||
If the result map contains more than 1 element and
|
||||
expect-single-result is true, then a MessagingException
|
||||
is thrown.
|
||||
|
||||
Otherwise the complete result map is returned as the
|
||||
payload.
|
||||
|
||||
Important Note: Several databases such as H2 are not
|
||||
fully supported for Stored Procedure and/oir Function calls.
|
||||
|
||||
|
||||
Important Note: Several databases such as H2 are not
|
||||
fully supported for Stored Procedure and/oir Function calls.
|
||||
|
||||
The H2 database, for example, does not fully support the CallableStatement
|
||||
semantics and when executing function calls against H2, a result list is
|
||||
returned, rather than a single value.
|
||||
|
||||
Therefore, even if you set expect-single-result = true,
|
||||
semantics and when executing function calls against H2, a result list is
|
||||
returned, rather than a single value.
|
||||
|
||||
Therefore, even if you set expect-single-result = true,
|
||||
you may end up with a collection being returned.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
@@ -1003,7 +1047,7 @@
|
||||
<xsd:documentation>
|
||||
Channel to which polled messages will be send. If the stored
|
||||
procedure or function does not return any data, the payload
|
||||
of the Message will be Null.
|
||||
of the Message will be Null.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
@@ -1043,7 +1087,7 @@
|
||||
<xsd:attribute name="auto-startup" type="xsd:string" default="true" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Flag to indicate that the poller should start automatically
|
||||
Flag to indicate that the poller should start automatically
|
||||
on startup (default true).
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -1052,7 +1096,7 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
If true, the JDBC parameter definitions for the stored procedure
|
||||
are not automatically derived from the underlying JDBC connection. In
|
||||
are not automatically derived from the underlying JDBC connection. In
|
||||
that case you must specify all Sql parameter definitions explicitly
|
||||
using the 'sql-parameter-definition' sub-element.
|
||||
</xsd:documentation>
|
||||
@@ -1061,20 +1105,20 @@
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:attributeGroup>
|
||||
|
||||
<xsd:complexType name="parameterSubElementType">
|
||||
</xsd:attributeGroup>
|
||||
|
||||
<xsd:complexType name="parameterSubElementType">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of stored procedure or function parameter.
|
||||
The name of stored procedure or function parameter.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="value" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The value of the parameter. Either this or the 'expression'
|
||||
The value of the parameter. Either this or the 'expression'
|
||||
attribute must be provided.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -1083,11 +1127,11 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The type of the value used. If nothing is provided this attribute
|
||||
will default to java.lang.String. This attribute is not used
|
||||
will default to java.lang.String. This attribute is not used
|
||||
when the 'expression' attribute is used instead.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -1097,24 +1141,24 @@
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
|
||||
<xsd:complexType name="returningResultSetRowMappersType">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the under which the resultset will be returned.
|
||||
The name of the under which the resultset will be returned.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="row-mapper" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:java.lang.Class"><![CDATA[
|
||||
The fully qualified class name of the row mapper.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
|
||||
<xsd:complexType name="sqlParameterDefinitionType">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
@@ -1126,38 +1170,38 @@
|
||||
<xsd:attribute name="direction" use="optional" default="IN">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the direction of the Sql parameter definition. Defaults
|
||||
to 'IN'. If your procedure is returning ResultSets, please
|
||||
use the 'returning-resultset' element.
|
||||
Specifies the direction of the Sql parameter definition. Defaults
|
||||
to 'IN'. If your procedure is returning ResultSets, please
|
||||
use the 'returning-resultset' element.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="sqlTypeDirection xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="type">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The Sql type used for this Sql parameter defintion. Will translate
|
||||
into the integer value as defined by java.sql.Types. Alternatively
|
||||
you can provide the integer value as well. If this attribute is
|
||||
you can provide the integer value as well. If this attribute is
|
||||
not explicitly set, then it will default to 'VARCHAR'.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="sqlType xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="scale" type="xsd:integer" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The scale of the Sql parameter. Only used for numeric and decimal
|
||||
parameters.
|
||||
parameters.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
|
||||
<xsd:simpleType name="sqlType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="VARCHAR"/>
|
||||
@@ -1198,12 +1242,12 @@
|
||||
<xsd:enumeration value="VARBINARY"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
|
||||
<xsd:simpleType name="sqlTypeDirection">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="IN"/>
|
||||
<xsd:enumeration value="OUT"/>
|
||||
<xsd:enumeration value="INOUT"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
@@ -16,6 +16,15 @@
|
||||
|
||||
package org.springframework.integration.jdbc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.integration.test.matcher.PayloadAndHeaderMatcher.sameExceptIgnorableHeaders;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -41,16 +50,6 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import static org.springframework.integration.test.matcher.PayloadAndHeaderMatcher.sameExceptIgnorableHeaders;
|
||||
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class JdbcMessageStoreTests {
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.jdbc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -20,90 +35,90 @@ public class StoredProcExecutorTest {
|
||||
|
||||
@Test
|
||||
public void testStoredProcExecutorWithNullDataSource() {
|
||||
|
||||
|
||||
try {
|
||||
new StoredProcExecutor(null, "storedProcedureName");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("dataSource must not be null.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoredProcExecutorWithNullProcedureName() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
|
||||
|
||||
try {
|
||||
new StoredProcExecutor(datasource, null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("storedProcedureName must not be null and cannot be empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testStoredProcExecutorWithEmptyProcedureName() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
|
||||
|
||||
try {
|
||||
new StoredProcExecutor(datasource, " ");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("storedProcedureName must not be null and cannot be empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetReturningResultSetRowMappersWithNullMap() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
|
||||
try {
|
||||
storedProcExecutor.setReturningResultSetRowMappers(null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("returningResultSetRowMappers must not be null.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetReturningResultSetRowMappersWithMapContainingNullValues() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
|
||||
Map<String, RowMapper<?>> rowmappers = new HashMap<String, RowMapper<?>>();
|
||||
rowmappers.put("results", null);
|
||||
|
||||
|
||||
try {
|
||||
storedProcExecutor.setReturningResultSetRowMappers(rowmappers);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("The provided map cannot contain null values.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetReturningResultSetRowMappersWithEmptyMap() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
|
||||
Map<String, RowMapper<?>> rowmappers = new HashMap<String, RowMapper<?>>();
|
||||
|
||||
storedProcExecutor.setReturningResultSetRowMappers(rowmappers);
|
||||
@@ -111,7 +126,7 @@ public class StoredProcExecutorTest {
|
||||
//Should Successfully finish
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetSqlParameterSourceFactoryWithNullParameter() {
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
@@ -123,53 +138,53 @@ public class StoredProcExecutorTest {
|
||||
assertEquals("sqlParameterSourceFactory must not be null.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetSqlParametersWithNullValueInList() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
List<SqlParameter> sqlParameters = new ArrayList<SqlParameter>();
|
||||
sqlParameters.add(null);
|
||||
|
||||
|
||||
try {
|
||||
storedProcExecutor.setSqlParameters(sqlParameters);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("The provided list (sqlParameters) cannot contain null values.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetSqlParametersWithEmptyList() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
List<SqlParameter> sqlParameters = new ArrayList<SqlParameter>();
|
||||
|
||||
|
||||
try {
|
||||
storedProcExecutor.setSqlParameters(sqlParameters);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("sqlParameters must not be null or empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetSqlParametersWithNullList() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
@@ -179,53 +194,53 @@ public class StoredProcExecutorTest {
|
||||
assertEquals("sqlParameters must not be null or empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetProcedureParametersWithNullValueInList() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
|
||||
procedureParameters.add(null);
|
||||
|
||||
|
||||
try {
|
||||
storedProcExecutor.setProcedureParameters(procedureParameters);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("The provided list (procedureParameters) cannot contain null values.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetProcedureParametersWithEmptyList() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
List<ProcedureParameter> procedureParameters = new ArrayList<ProcedureParameter>();
|
||||
|
||||
|
||||
try {
|
||||
storedProcExecutor.setProcedureParameters(procedureParameters);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("procedureParameters must not be null or empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetProcedureParametersWithNullList() {
|
||||
|
||||
|
||||
DataSource datasource = mock(DataSource.class);
|
||||
StoredProcExecutor storedProcExecutor = new StoredProcExecutor(datasource, "storedProcedureName");
|
||||
|
||||
@@ -235,9 +250,9 @@ public class StoredProcExecutorTest {
|
||||
assertEquals("procedureParameters must not be null or empty.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Exception expected.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
package org.springframework.integration.jdbc.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -60,6 +61,19 @@ public class StoredProcOutboundGatewayParserTests {
|
||||
assertEquals("Wrong stored procedure name", "GET_PRIME_NUMBERS", storedProcedureName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipUndeclaredResultsAttributeSet() throws Exception {
|
||||
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
|
||||
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(this.outboundGateway);
|
||||
Object source = accessor.getPropertyValue("handler");
|
||||
accessor = new DirectFieldAccessor(source);
|
||||
source = accessor.getPropertyValue("executor");
|
||||
accessor = new DirectFieldAccessor(source);
|
||||
boolean skipUndeclaredResults = (Boolean) accessor.getPropertyValue("skipUndeclaredResults");
|
||||
assertFalse(skipUndeclaredResults);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedurepParametersAreSet() throws Exception {
|
||||
setUp("storedProcOutboundGatewayParserTest.xml", getClass());
|
||||
|
||||
@@ -60,6 +60,19 @@ public class StoredProcPollingChannelAdapterParserTests {
|
||||
assertEquals("Wrong stored procedure name", "GET_PRIME_NUMBERS", storedProcedureName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipUndeclaredResultsAttributeSet() throws Exception {
|
||||
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
|
||||
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(this.pollingAdapter);
|
||||
Object source = accessor.getPropertyValue("source");
|
||||
accessor = new DirectFieldAccessor(source);
|
||||
source = accessor.getPropertyValue("executor");
|
||||
accessor = new DirectFieldAccessor(source);
|
||||
boolean skipUndeclaredResults = (Boolean) accessor.getPropertyValue("skipUndeclaredResults");
|
||||
assertTrue("skipUndeclaredResults was not set and should default to 'true'", skipUndeclaredResults);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedurepParametersAreSet() throws Exception {
|
||||
setUp("storedProcPollingChannelAdapterParserTest.xml", getClass());
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<int:channel id="requestChannel"/>
|
||||
<int:channel id="replyChannel"/>
|
||||
|
||||
|
||||
<jdbc:embedded-database id="datasource" type="HSQL"/>
|
||||
|
||||
<int-jdbc:stored-proc-outbound-gateway request-channel="requestChannel" stored-procedure-name="GET_PRIME_NUMBERS" data-source="datasource"
|
||||
@@ -19,15 +19,16 @@
|
||||
id="storedProcedureOutboundGateway"
|
||||
ignore-column-meta-data="false"
|
||||
is-function="false"
|
||||
skip-undeclared-results="false"
|
||||
order="2"
|
||||
reply-channel="replyChannel"
|
||||
request-timeout="555"
|
||||
return-value-required="false">
|
||||
|
||||
|
||||
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
|
||||
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
|
||||
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
|
||||
<int-jdbc:sql-parameter-definition name="description" />
|
||||
<int-jdbc:sql-parameter-definition name="description" />
|
||||
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
|
||||
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
|
||||
<int-jdbc:parameter name="password" expression="payload.username"/>
|
||||
@@ -35,6 +36,6 @@
|
||||
<int-jdbc:returning-resultset name="out" row-mapper="org.springframework.integration.jdbc.storedproc.PrimeMapper"/>
|
||||
|
||||
</int-jdbc:stored-proc-outbound-gateway>
|
||||
|
||||
|
||||
<int:poller default="true" fixed-rate="10000"/>
|
||||
</beans>
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.jdbc.storedproc;
|
||||
|
||||
public interface CreateUser {
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.jdbc.storedproc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -14,7 +29,7 @@ public class ProcedureParameterTest {
|
||||
|
||||
@Test
|
||||
public void testProcedureParameterStringObjectString() {
|
||||
|
||||
|
||||
try {
|
||||
new ProcedureParameter(null, "value", "expression");
|
||||
} catch(IllegalArgumentException e) {
|
||||
@@ -28,58 +43,58 @@ public class ProcedureParameterTest {
|
||||
@Test
|
||||
public void testConvertExpressions() {
|
||||
List<ProcedureParameter> procedureParameters = getProcedureParameterList();
|
||||
Map<String, String> expressionParameters =
|
||||
Map<String, String> expressionParameters =
|
||||
ProcedureParameter.convertExpressions(procedureParameters);
|
||||
|
||||
|
||||
assertTrue("Expected 2 expression parameters.", expressionParameters.size() == 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertStaticParameters() {
|
||||
|
||||
|
||||
List<ProcedureParameter> procedureParameters = getProcedureParameterList();
|
||||
Map<String, Object> staticParameters =
|
||||
Map<String, Object> staticParameters =
|
||||
ProcedureParameter.convertStaticParameters(procedureParameters);
|
||||
|
||||
|
||||
assertTrue("Expected 3 static parameters.", staticParameters.size() == 3);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConvertStaticParametersWithNullValueInList() {
|
||||
|
||||
|
||||
List<ProcedureParameter> procedureParameters = getProcedureParameterList();
|
||||
procedureParameters.add(1, null);
|
||||
|
||||
|
||||
try {
|
||||
ProcedureParameter.convertStaticParameters(procedureParameters);
|
||||
} catch(IllegalArgumentException e) {
|
||||
assertEquals("'procedureParameters' must not contain null values.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Expected Exception");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConvertExpressionParametersWithNullValueInList() {
|
||||
|
||||
|
||||
List<ProcedureParameter> procedureParameters = getProcedureParameterList();
|
||||
procedureParameters.add(1, null);
|
||||
|
||||
|
||||
try {
|
||||
ProcedureParameter.convertExpressions(procedureParameters);
|
||||
} catch(IllegalArgumentException e) {
|
||||
assertEquals("'procedureParameters' must not contain null values.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fail("Expected Exception");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private List<ProcedureParameter> getProcedureParameterList() {
|
||||
|
||||
|
||||
List<ProcedureParameter> procedureParameterList = new ArrayList<ProcedureParameter>();
|
||||
procedureParameterList.add(new ProcedureParameter("param1", "value1", null));
|
||||
procedureParameterList.add(new ProcedureParameter("param2", "value1", null));
|
||||
|
||||
Reference in New Issue
Block a user