
Originally Posted by
cyboc
I followed Joe's solution and got it to work with DB2. Thanks.
However I want to optimize it a bit to only set the current schema if needed. As it is now it will set it for every call to the database.
Code:
27 Oct 2004 09:42:21 DEBUG com.bmd.spring.SchemaAwareDataSourceProxy - Setting schema to xx on connection org.apache.commons.dbcp.PoolableConnection@1a28362
27 Oct 2004 09:42:22 DEBUG com.bmd.spring.SchemaAwareDataSourceProxy - Setting schema to xx on connection org.apache.commons.dbcp.PoolableConnection@1a28362
27 Oct 2004 09:42:23 DEBUG com.bmd.spring.SchemaAwareDataSourceProxy - Setting schema to zbonpgmmdl on connection org.apache.commons.dbcp.PoolableConnection@1a28362
Hibernate: select synonfile0_.ØØFIL as ØØFIL, synonfile0_.objatr as objatr, synonfile0_.fil as fil, synonfile0_.srcmbr as srcmbr, synonfile0_.rpgpfx as rpgpfx, synonfile0_.olddbs as olddbs from zbonpgmmdl.YFILDTARFP synonfile0_ where (synonfile0_.srcmbr=? )
27 Oct 2004 09:42:24 DEBUG com.bmd.spring.SchemaAwareDataSourceProxy - Setting schema to zbonpgmmdl on connection org.apache.commons.dbcp.PoolableConnection@1a28362
Hibernate: select synonnarra1_.ØØOBJ as ØØOBJ, synonnarra1_.txttyp as txttyp, synonnarra1_.pagnbr as pagnbr, synonnarra1_.l01 as l01, synonnarra1_.l02 as l02, synonnarra1_.l03 as l03, synonnarra1_.l04 as l04, synonnarra1_.l05 as l05, synonnarra1_.l06 as l06, synonnarra1_.l07 as l07, synonnarra1_.l08 as l08, synonnarra1_.l09 as l09, synonnarra1_.l10 as l10, synonnarra1_.l11 as l11, synonnarra1_.l12 as l12, synonnarra1_.l13 as l13, synonnarra1_.l14 as l14, synonnarra1_.l15 as l15, synonnarra1_.l16 as l16, synonnarra1_.l17 as l17, synonnarra1_.l18 as l18 from zbonpgmmdl.YRELDTARFP synonrelat0_, zbonpgmmdl.YTXTDTARFP synonnarra1_ where (synonrelat0_.ØØOBJ=? )AND(synonrelat0_.relcde='005' )AND(synonrelat0_.ØØOBJ=synonnarra1_.ØØOBJ )
27 Oct 2004 09:42:25 DEBUG com.bmd.spring.SchemaAwareDataSourceProxy - Setting schema to zbonpgmmdl on connection org.apache.commons.dbcp.PoolableConnection@1a28362
Hibernate: select synonfield1_.ØØFLD as ØØFLD, synonfield1_.fld as fld, synonfield1_.ØØDOM as ØØDOM, synonfield1_.rhshdg as rhshdg, synonfield1_.ddsvnm as ddsvnm, synonfield1_.lhshdg as lhshdg from zbonpgmmdl.YRELDTARFP synonrelat0_, zbonpgmmdl.YFLDDTARFP synonfield1_ where (synonrelat0_.ØØOBJ=? )AND(synonrelat0_.relcde='060' )AND(synonrelat0_.ØØREF=synonfield1_.ØØFLD )
27 Oct 2004 09:42:25 DEBUG com.bmd.spring.SchemaAwareDataSourceProxy - Setting schema to zbonpgmmdl on connection org.apache.commons.dbcp.PoolableConnection@1a28362
My use-case is pr. HttpSession tu use the same DB schema. So I want to store the schemanme in the HttpSession and set it as a ThreadLocal attribute that the SchemaAwareDataSourceProxy holds and thus has this information and can determine if it needs to set the current schema on the Connection object.
Since I will use a connection pool I can get an arbitrary Connection object from the pool that has its current schema set to something I do not know.
How do I store the schemaname that the Connection object has set?
My idea is to create a ConnectionSchemaWrapper object that delegates to the real Connection object but also stores its current schema settings - getSchemaName().
Then I can check in my SchemaAwareDataSourceProxy object:
Code:
Connection con = super.getConnection();
ConnectionSchemaWrapper wrapper = (ConnectionSchemaWrapper) con;
if (! schemaName.equals(wrapper.getSchemaName())
setSchemaOnConnection(con, schemaName);
Is there a better aprroach to link the Connection with the schema it has currently been set to?
And here is my simple proxy code
Code:
public class SchemaAwareDataSourceProxy extends TransactionAwareDataSourceProxy {
// TODO: Connection wrapper to store current set schema name
private final Log logger = LogFactory.getLog(getClass());
private final ThreadLocal schema = new ThreadLocal();
public void setSchemaName(String schemaName) {
schema.set(schemaName);
}
public Connection getConnection() throws SQLException {
Connection con = super.getConnection();
String schemaName = (String) schema.get();
if (schemaName == null)
throw new IllegalStateException("SchemaName not set. Call setSchemaName before doing any database access");
setSchemaOnConnection(con, schemaName);
return con;
}
private void setSchemaOnConnection(Connection con, String schemaName) throws SQLException {
if (logger.isDebugEnabled())
logger.debug("Setting schema to " + schemaName + " on connection " + con);
Statement stmt = con.createStatement();
try {
// DB2 specific SQL. Oracle uses different syntax.
stmt.execute("set current schema = " + schemaName);
} finally {
stmt.close();
}
}
And the spring .xml
Code:
<!-- Our datasource that is capable of setting thread-bound schma name -->
<bean id="dataSource" class="com.bmd.spring.SchemaAwareDataSourceProxy">
<property name="targetDataSource"><ref local="dataSourceTarget"/></property>
<property name="schemaName"><value>xx</value></property>
</bean>
<bean id="dataSourceTarget" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"><value>com.p6spy.engine.spy.P6SpyDriver</value></property>
<property name="url"><value>jdbc:as400://XXX;translate binary=true</value></property>
<property name="username"><value>XXX</value></property>
<property name="password"><value>XXX</value></property>
</bean>
And how to change the schema name for the current thread.
Code:
SchemaAwareDataSourceProxy s = (SchemaAwareDataSourceProxy) app.getBean("dataSource");
s.setSchemaName("zbonpgmmdl");
[/code]