Skip to content

Unwrap DataSource hidden behind InfrastructureProxy in SqlScriptsTestExecutionListener #26422

@stolsvik

Description

@stolsvik

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.).

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions