简单-高效-优雅

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中还是有不少经验总结的

posted on 2008-08-26 14:35 BigOnion 阅读(1048) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: