in method SqlScriptsTestExecutionListener.executeSqlScripts(...), around line 213, the following code resides:
DataSource dataSourceFromTxMgr = getDataSourceFromTransactionManager(txMgr);
// Ensure user configured an appropriate DataSource/TransactionManager pair.
if (dataSource != null && dataSourceFromTxMgr != null && !dataSource.equals(dataSourceFromTxMgr)) {
throw new IllegalStateException(String.format("Failed to execute SQL scripts for test context %s: " +
"the configured DataSource [%s] (named '%s') is not the one associated with " +
"transaction manager [%s] (named '%s').", testContext, dataSource.getClass().getName(),
dsName, txMgr.getClass().getName(), tmName));
}
This seems to contradict the logic used in DataSourceUtils which handles such equality checks taking into account that a DataSource may be an implementation of InfrastrutureProxy.
We have a setup where the DataSource in the Spring context is directly the database DataSource (well, it is pooled), while the DataSource given to the DataSourceTransactionManager is a wrapped version. However, the wrapping class implements InfrastructureProxy, which ensures that all Spring JDBC stuff - which utilizes the DataSourceUtils class to fetch (and release) Connections - actually handles this perfectly: Even though e.g. the JdbcTemplate has gotten the "plain" DataSource, while, again, the TxMgr has the wrapped DataSource, when in a Spring managed Transaction, the JdbcTemplate ends up with Connections from the wrapped DataSource (in the DataSourceTransactionManager) due to the logic wrt. InfrastructureProxy in DataSourceUtils.
However, this is not the case in SqlScriptsTestExecutionListener, due to the much plainer .equals(..) check being performed there. Basically, had the check not been there, it would have worked. Also, had the check taken into account the InfrastructureProxy logic, it would also have worked.
(And, due to the equality being checked is dataSourceFromSpringContext.equals(dataSourceFromTxMgr) - and not the other way around - I cannot hack this to work either. The only way around that would be to also wrap the DataSource in the Spring context too (to trick the .equals(..)) - in which case I could just as well put the same DataSource in Spring context as the one given to the DataSourceTransactionManager, which of course would fix this. However, the problem is that these two are handled in different code bases, and it is not always the situation that we want to do that wrapping of the DataSource given to the DataSourceTransactionManager.).
in method
SqlScriptsTestExecutionListener.executeSqlScripts(...), around line 213, the following code resides:This seems to contradict the logic used in
DataSourceUtilswhich handles such equality checks taking into account that aDataSourcemay be an implementation ofInfrastrutureProxy.We have a setup where the
DataSourcein the Spring context is directly the databaseDataSource(well, it is pooled), while theDataSourcegiven to theDataSourceTransactionManageris a wrapped version. However, the wrapping class implementsInfrastructureProxy, which ensures that all Spring JDBC stuff - which utilizes theDataSourceUtilsclass to fetch (and release) Connections - actually handles this perfectly: Even though e.g. theJdbcTemplatehas gotten the "plain"DataSource, while, again, the TxMgr has the wrappedDataSource, when in a Spring managed Transaction, theJdbcTemplateends up with Connections from the wrappedDataSource(in theDataSourceTransactionManager) due to the logic wrt.InfrastructureProxyinDataSourceUtils.However, this is not the case in
SqlScriptsTestExecutionListener, due to the much plainer.equals(..)check being performed there. Basically, had the check not been there, it would have worked. Also, had the check taken into account theInfrastructureProxylogic, it would also have worked.(And, due to the equality being checked is
dataSourceFromSpringContext.equals(dataSourceFromTxMgr)- and not the other way around - I cannot hack this to work either. The only way around that would be to also wrap theDataSourcein the Spring context too (to trick the.equals(..)) - in which case I could just as well put the sameDataSourcein Spring context as the one given to theDataSourceTransactionManager, which of course would fix this. However, the problem is that these two are handled in different code bases, and it is not always the situation that we want to do that wrapping of theDataSourcegiven to theDataSourceTransactionManager.).