Environment:
Database - Oracle 10i
App Server - OC4J 10.1.3.5.0
JDK - 1.5.0_09
I am required by design to interact with the database solely through stored procedures/functions and user-defined types. To this end I have created a collection of classes that extend org.springframework.jdbc.object.StoredProcedure. I use JNDI to lookup the datasource and so I have also created a class that extends org.springframework.jndi.JndiObjectFactoryBean and I have overridden getObject() as such:
My stored procedure class looks like this:Code:public class CustomJndiObjectFactoryBean extends JndiObjectFactoryBean { @Override public DataSource getObject() { System.out.println("-- GETTING DATASOURCE --"); DataSource ds = (DataSource)super.getObject(); try { ds.getConnection().setTypeMap(MGFEMappings.TYPE_MAP); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return ds; } }
Both my dataSource and my stored procedure object are configured in the applicationContext.xml as:Code:public class FnGetUserByName extends StoredProcedure { private static final String SF_NAME = "pkg_user.sf_get_user"; public FnGetUserByName(DataSource dataSource) { super(dataSource, SF_NAME); try { System.out.println("--Creating FnGetUserByName--" + this.getJdbcTemplate().getDataSource().getConnection().getTypeMap().get(User.SQLTypeName)); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } setFunction(true); declareParameter(new SqlOutParameter("user", Types.STRUCT, User.SQLTypeName)); declareParameter(new SqlParameter("userName", Types.VARCHAR)); compile(); } public User execute(String userName) { try { System.out.println("--Executing FnGetUserByName--" + this.getJdbcTemplate().getDataSource().getConnection().getTypeMap().get(User.SQLTypeName)); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } Map<String, Object> inParams = new HashMap<String, Object>(1); inParams.put("userName", userName); Map<String, Object> outParams = execute(inParams); User user = null; if(outParams.size() > 0) { try { user = (User) outParams.get("user"); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return user; } }
However when I run my app, the debug code shows:Code:<bean id="dataSource" class="editor.util.CustomJndiObjectFactoryBean"> <property name="jndiName" value="jdbc/MyDS" /> </bean> <bean id="fnGetUserByName" class="editor.hibernate.dao.function.FnGetUserByName"> <constructor-arg><ref bean="dataSource"/></constructor-arg> </bean>
11/01/28 13:13:01 --Creating FnGetUserByName--class editor.hibernate.model.User
11/01/28 13:13:02 --Executing FnGetUserByName--null
and then of course I get the error:
11/01/28 13:13:03 java.lang.ClassCastException: oracle.sql.STRUCT
So what happens between the time the class is instantiated and the time the execute method is called that the connection type map is getting clobbered?
Is there a better way to set the type map than by overriding getObject()?
I've been banging my head on this one for a while now so any help would be appreciated.


Reply With Quote
