Imagine this code:
foo() {
Connection conn = ...;
}
foo()
has been called from a method that has the annotation @Transactional
. How do I get the current JDBC connection? Note that foo()
is in a bean (so it can have @Autowired
fields) but foo()
can't have parameters (so I can't pass the connection in from somewhere).
[EDIT] I'm using jOOQ which needs either a data source or a connection. My problem: I don't know which transaction manager is configured. It could be anything; Java EE, DataSource based, something which gets the data source via JNDI. My code isn't an application, it's a library. I need to swallow what others put on my plate. Along the same lines, I can't request a Hibernate session factory because the application using me might not use Hibernate.
But I know that other code, like the Spring Hibernate integration, somehow can get the current connection from the transaction manager. I mean, Hibernate doesn't support Spring's transaction manager, so the glue code must adapt the Spring API to what Hibernate expects. I need to do the same thing but I couldn't figure out how it works.
[EDIT2] I know that there is an active transaction (i.e. Spring has a Connection instance somewhere or at least a transaction manager which can create one) but my method isn't @Transactional. I need to call a constructor which takes java.sql.Connection
as parameter. What should I do?
You can probably try DataSourceUtils.getConnection(dataSource)
, per the API it should return you the current connection for the datasource.
Update:
Based on your comments and the source code for org.springframework.transaction.support.TransactionSynchronizationManager
:
Like I said, the key to getting the connection is the datasource name, if this cannot be obtained, one way out by looking at the source code is to try this:
TransactionSynchronizationManager.getResourceMap()
will return a map of datasource to ConnectionHolder in the current thread, assuming that you have only 1 resource involved in transaction, you can probably do a map.values().get(0)
to get the first ConnectionHolder, from which you can get a connection by calling .getConnection()
So essentially calling the following:
TransactionSynchronizationManager.getResourceMap().values().get(0).getConnection()
There probably has to be better way though :-)