I want to use CopyManager from postgres JDBC for one of my project. However I'm having a problem with getting an instance of this object from a sessionFactory in a Grails project.
This is my current approach:
SessionFactoryImpl sessionFactoryImpl = (sessionFactory.currentSessionFactory as SessionFactoryImpl)
LazyConnectionDataSourceProxy lcdsProxy = java.lang.reflect.Proxy.getInvocationHandler(sessionFactoryImpl.connectionProvider.connection).targetDataSource
DisposableConnectionFacade dcFacade = java.lang.reflect.Proxy.getInvocationHandler(lcdsProxy.targetDataSource.connection)
Jdbc4Connection jdbc4Connection = dcFacade.next.connection.connection
CopyManager cm = (jdbc4Connection as BaseConnection).copyAPI
I'm sure there must be simpler way how to unwrap JDBC4 connection from session factory.
Unfortunately since the DataSource
is proxied 3 times, to get the real implementation of the connection and Postgres Jdbc4Connection, you either need to dig down through the DataSource
proxies, or the connection proxies. I'd use more idiomatic Groovy though and skip using the 'current' session factory, since the sessionFactory
proxy will pass all calls to the real instance (plus I'm pretty sure that would fail in a WAR file since this is only active in dev to support reloading):
import java.lang.reflect.Proxy
def lcdsProxy = Proxy.getInvocationHandler(sessionFactory.connectionProvider.connection).targetDataSource
def dcFacade = Proxy.getInvocationHandler(lcdsProxy.targetDataSource.connection)
def jdbc4Connection = dcFacade.next.connection.connection
CopyManager cm = jdbc4Connection.copyAPI
My preference would be to get the connection from the current session, not the current session factory, since that's what holds the connection, and one of those 3 proxies is a org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
to ensure that the connection being used by the current session would be returned from the DataSource
as a 'new' connection. So one approach there would be
def connection = sessionFactory.currentSession.connection()
def jdbc4Connection = connection.targetConnection.targetConnection.connection
CopyManager cm = jdbc4Connection.copyAPI
or if this is the only reason you need the sessionFactory
, you could use withSession
:
AnyDomainClass.withSession { session ->
def connection = session.connection()
def jdbc4Connection = connection.targetConnection.targetConnection.connection
CopyManager cm = jdbc4Connection.copyAPI
}
or even skip that and go to the DataSource
(dependency-injected with def dataSource
) since one of the datasource proxies is a TransactionAwareDataSourceProxy
:
def connection = ctx.dataSource.connection
def jdbc4Connection = connection.targetConnection.targetConnection.connection
CopyManager cm = jdbc4Connection.copyAPI
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.