JBoss下CLOB.createTemporary抛出ClassCast的异常

JBoss下CLOB.createTemporary抛出ClassCast的异常

错误用法:CLOB.createTemporary(conn,....);
正确用法:CLOB.createTemporary(((WrappedConnection) con).getUnderlyingConnection() ,.....);
原理:
=================================================================
if you are using jboss or any other AS that perform jdbc connection pooling , the classcast exception is caused by the "conn" object. (I had this problem using jboss4.0.1/oracle9.2).
In jboss4 the Connection object retrieved by ConnectionFactory.makeconnection() is an instance of org.jboss.resource.adapter.jdbc.WrappedConnection class (or a DelegatingConnection in tomcat or products that use DBCP)
=================================================================
include jboss-common-jdbc-wrapper.jar with WrappedConnection class

=============================《2008-9-10》=======================
最近看了看人家Spring,老早处理了这种情况了,具体见NativeJdbcExtractor接口
public   interface  NativeJdbcExtractor {    
   
boolean  isNativeConnectionNecessaryForNativeStatements();

    
boolean  isNativeConnectionNecessaryForNativePreparedStatements();

    
boolean  isNativeConnectionNecessaryForNativeCallableStatements();

   
// 呵呵,就是这个方法
    Connection getNativeConnection(Connection con)  throws  SQLException;

    Connection getNativeConnectionFromStatement(Statement stmt) 
throws  SQLException;

    Statement getNativeStatement(Statement stmt) 
throws  SQLException;

    PreparedStatement getNativePreparedStatement(PreparedStatement ps) 
throws  SQLException;

    CallableStatement getNativeCallableStatement(CallableStatement cs) 
throws  SQLException;

    ResultSet getNativeResultSet(ResultSet rs) 
throws  SQLException;

}

来看看,Jboss的特定实现:
public   class  JBossNativeJdbcExtractor  extends  NativeJdbcExtractorAdapter {

    
private   static   final  String WRAPPED_CONNECTION_NAME  =   " org.jboss.resource.adapter.jdbc.WrappedConnection " ;

    
private   static   final  String WRAPPED_STATEMENT_NAME  =   " org.jboss.resource.adapter.jdbc.WrappedStatement " ;

    
private   static   final  String WRAPPED_RESULT_SET_NAME  =   " org.jboss.resource.adapter.jdbc.WrappedResultSet " ;


    
private  Class wrappedConnectionClass;

    
private  Class wrappedStatementClass;

    
private  Method getUnderlyingConnectionMethod;

    
private  Method getUnderlyingStatementMethod;


    
/**
     * This constructor retrieves JBoss JDBC wrapper classes,
     * so we can get the underlying vendor connection using reflection.
     
*/
    
public  JBossNativeJdbcExtractor() {
        
try  {
            
this .wrappedConnectionClass  =  getClass().getClassLoader().loadClass(WRAPPED_CONNECTION_NAME);
            
this .wrappedStatementClass  =  getClass().getClassLoader().loadClass(WRAPPED_STATEMENT_NAME);
            
this .getUnderlyingConnectionMethod  =
                
this .wrappedConnectionClass.getMethod( " getUnderlyingConnection " , (Class[])  null );
            
this .getUnderlyingStatementMethod  =
                
this .wrappedStatementClass.getMethod( " getUnderlyingStatement " , (Class[])  null );
        }
        
catch  (Exception ex) {
            
throw   new  DASEntityRuntimeException(ExceptionConstant.DAS_14101034,
                            
" Could not initialize JBossNativeJdbcExtractor because JBoss API classes are not available " ,
                            ex);
        }
    }


    
/**
     * Retrieve the Connection via JBoss' <code>getUnderlyingConnection</code> method.
     
*/
    
protected  Connection doGetNativeConnection(Connection con)  throws  SQLException {
        
if  ( this .wrappedConnectionClass.isAssignableFrom(con.getClass())) {
            
try  {
                
return  (Connection)  this .getUnderlyingConnectionMethod.invoke(con, (Object[])  null );
            }
            
catch  (InvocationTargetException ex) {
                
throw   new  DASEntityRuntimeException(ExceptionConstant.DAS_14101034,
                        
" JBoss' getUnderlyingConnection method failed " , ex
                                .getTargetException());
            }
            
catch  (Exception ex) {
                
throw   new  DASEntityRuntimeException(ExceptionConstant.DAS_14101034,
                                
" Could not access JBoss' getUnderlyingConnection method " ,
                                ex);
            }
        }
        
return  con;
    }

    
/**
     * Retrieve the Connection via JBoss' <code>getUnderlyingStatement</code> method.
     
*/
    
public  Statement getNativeStatement(Statement stmt)  throws  SQLException {
        
if  ( this .wrappedStatementClass.isAssignableFrom(stmt.getClass())) {
            
try  {
                
return  (Statement)  this .getUnderlyingStatementMethod.invoke(stmt, (Object[])  null );
            }
            
catch  (InvocationTargetException ex) {
                
throw   new  DASEntityRuntimeException(ExceptionConstant.DAS_14101034,
                        
" JBoss' getUnderlyingStatement method failed " , ex
                                .getTargetException());
            }
            
catch  (Exception ex) {
                
throw   new  DASEntityRuntimeException(ExceptionConstant.DAS_14101034,
                                
" Could not access JBoss' getUnderlyingStatement method " ,
                                ex);
            }
        }
        
return  stmt;
    }

    
/**
     * Retrieve the Connection via JBoss' <code>getUnderlyingStatement</code> method.
     
*/
    
public  PreparedStatement getNativePreparedStatement(PreparedStatement ps)  throws  SQLException {
        
return  (PreparedStatement) getNativeStatement(ps);
    }

    
/**
     * Retrieve the Connection via JBoss' <code>getUnderlyingStatement</code> method.
     
*/
    
public  CallableStatement getNativeCallableStatement(CallableStatement cs)  throws  SQLException {
        
return  (CallableStatement) getNativeStatement(cs);
    }

    
/**
     * Retrieve the Connection via JBoss' <code>getUnderlyingResultSet</code> method.
     * <p>We access WrappedResultSet via direct reflection, since this class only
     * appeared in JBoss 3.2.4 and we want to stay compatible with at least 3.2.2+.
     
*/
    
public  ResultSet getNativeResultSet(ResultSet rs)  throws  SQLException {
        
if  (rs.getClass().getName().equals(WRAPPED_RESULT_SET_NAME)) {
            
try  {
                Method getUnderlyingResultSetMethod 
=  rs.getClass().getMethod( " getUnderlyingResultSet " , (Class[])  null );
                
return  (ResultSet) getUnderlyingResultSetMethod.invoke(rs, (Object[])  null );
            }
            
catch  (InvocationTargetException ex) {
                
throw   new  DASEntityRuntimeException(ExceptionConstant.DAS_14101034,
                        
" JBoss' getUnderlyingResultSet method failed " , ex
                                .getTargetException());
            }
            
catch  (Exception ex) {
                
throw   new  DASEntityRuntimeException(ExceptionConstant.DAS_14101034,
                                
" Could not access JBoss' getUnderlyingResultSet method " ,
                                ex);
            }
        }
        
return  rs;
    }

}
看来Spring中还是有不少经验总结的

你可能感兴趣的:(JBoss下CLOB.createTemporary抛出ClassCast的异常)