为什么java.sql.Connection中不能转换为oracle.jdbc.OracleConnection在下面的代码?
我的主要目标是通过对Oracle连接新的用户名,并将其保存在例如“OSUSER”列“会话”表,因为我想在DB用户更改跟踪,并在表中显示。
@Repository
public class AuditLogDAOImpl implements AuditLogDAO {
@PersistenceContext(unitName="myUnitName")
EntityManager em;
@Resource(name = "dataSource")
DataSource dataSource;
public void init() {
try {
Connection connection = DataSourceUtils.getConnection(dataSource);
OracleConnection oracleConnection = (OracleConnection) connection; //Here I got cast exception!
String metrics[] = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];
metrics[OracleConnection.END_TO_END_CLIENTID_INDEX] = "my_new_username";
oracleConnection.setEndToEndMetrics(metrics, (short) 0);
java.util.Properties props = new java.util.Properties();
props.put("osuser", "newValue");
oracleConnection.setClientInfo(props);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
下面是错误日志:
10:42:29,251 INFO [STDOUT] org.jboss.resource.adapter.jdbc.jdk6.WrappedConnectionJDK6@bcc8cb
10:42:51,701 ERROR [STDERR] java.lang.ClassCastException: $Proxy286 cannot be cast to oracle.jdbc.OracleConnection
一般来说,我在这种情况下,2问题:
- 为什么从连接转换为的OracleConnection失败,
- 什么是执行我的打算(我的意思是Oracle数据库中设置新的用户名以V $ session.osuser的最佳方式?
我与Oracle 11g中,休眠(使用实体管理器),通过JNDI数据源工作。
请帮帮忙,谢谢!
编辑:
一些改进后,仍然存在与铸造的问题。
改进:
Connection connection = DataSourceUtils.getConnection(dataSource);
connection = ((org.jboss.resource.adapter.jdbc.WrappedConnection)connection).getUnderlyingConnection();
OracleConnection oracleConnection = (OracleConnection) connection;
错误:
java.lang.ClassCastException: $Proxy287 cannot be cast to org.jboss.resource.adapter.jdbc.WrappedConnection
Answer 1:
要检索的连接可能是一个包裹连接。
如果你真的需要得到底层Oracle连接,您应该使用:
if (connection.isWrapperFor(OracleConnection.class)){
OracleConnection oracleConnection= connection.unwrap(OracleConnection.class);
}else{
// recover, not an oracle connection
}
该isWrapperFor
和unwrap
的方法是从Java 1.6可用,并且应该由A / S连接包装进行有意义的实现。
Answer 2:
连接池通常有真正的连接实例周围的包装,这就是为什么你的施法失败。
你在做什么不反正工作,因为在属性实例的参数在建立连接时,只检查。 当你有一个已激活的连接,它不会改变任何东西。
你需要使用土特产品DBMS_APPLICATION_INFO.SET_CLIENT_INFO()
为了改变这种现有连接。
Answer 3:
这仅仅是通过谁如何在设定的OracleConnection搜索的指标来这里的人,我花很多时间在这个大便宜,所以可能会帮助别人。
你得到你的“连接”后,这应该工作:
DatabaseMetaData dmd = connection.getMetaData();
Connection metaDataConnection = null;
if(dmd != null)
{
metaDataConnection = dmd.getConnection();
}
if(!(metaDataConnection instanceof OracleConnection))
{
log.error("Connection is not instance of OracleConnection, returning");
return; /* Not connection u want */
}
OracleConnection oraConnection = (OracleConnection)metaDataConnection;
String[] metrics = new String[END_TO_END_STATE_INDEX_MAX]; // Do the rest below...
它为我的OracleConnection,但我面对的设定指标时,差异的问题:
short zero = 0;
oraConnection.setEndToEndMetrics(metrics, zero);
通过我的方法,我设置的指标几次进行代理连接后,我得到:
java.sql.SQLRecoverableException: No more data to read from socket
但我认为它有一些弹簧接线inits或连接池做。
Answer 4:
用春天的时候让我连接了面临这个问题。 典型地,每个层增加了在基本类的包装。 我刚刚做connection.getClass()的getName()来查看连接的运行时类型进行重新调整。 这将是一个包装/代理了,你可以很容易地找到得到基本的OracleConnection类型的方法。
Answer 5:
您可以访问内部OracleObject一个包装里面,在这种情况下,封装类型为NewProxyConnection:
(我在我的项目中使用它,它的工作...没有谜,只需要使用反射)
Field[] fieldsConn= connection.getClass().getDeclaredFields();
Object innerConnObject = getFieldByName(fieldsConn,"inner").get(connection);
if(innerConnObject instanceof OracleConnection ){
OracleConnection oracleConn = (OracleConnection)innerConnObject;
//OracleConnection unwrap = ((OracleConnection)innerConnObject).unwrap();
// now you have the OracleObject that the Wrapper
}
//Method: Set properties of the ooject accessible.
public static Field getFieldByName(Field[] campos, String name) {
Field f = null;
for (Field campo : campos) {
campo.setAccessible(true);
if (campo.getName().equals(name)) {
f = campo;
break;
}
}
return f;
}
Answer 6:
请尝试以下
我曾遇到同样的问题。 我们使用的弹簧,它有一个叫NativeJdbcExtractor类。 它有许多的实现和下面一个作品为Tomcat。 有一个具体的实施对于JBoss称为JBossNativeJdbcExtractor
<bean id="jdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"></bean>
在你的DAO,你可以注入豆,用下面的方法
protected NativeJdbcExtractor jdbcExtractor;
Connection conn=jdbcExtractor.getNativeConnection(oracleConnection);
Answer 7:
不知道我的情况是相关的,但我的项目,只需更改数据库配置设置实际上会展开失败!
我使用Scala的播放框架; 这个工作对我来说,只有当logSql = FALSE :
db.withConnection { implicit c =>
val oracleConnection = c.unwrap(classOf[OracleConnection])
}
(这只是展开一个OracleConnection的斯卡拉版)
当我设置logSql =真 ,我得到:
。com.sun.proxy $ Proxy17不能转换到oracle.jdbc.OracleConnection java.lang.ClassCastException:com.sun.proxy $ Proxy17不能转换为oracle.jdbc.OracleConnection
因此,一些关于logSql配置实际上可以导致展开失败。 不知道为什么。
无论使用哪种配置,我的连接对象是:
HikariProxyConnection @ 1880261898个包装oracle.jdbc.driver.T4CConnection@6b28f065
isWrapperFor(OracleConnection)
是在两种情况下真
这种情况与阿光连接池和骨CP。 也许这是在甲骨文JDBC中的错误?
根据MANIFEST.MF的Oracle JDBC驱动程序版本
实现的版本:11.2.0.3.0
库ID:JAVAVM_11.2.0.4.0_LINUX.X64_130711
Answer 8:
经过反复试验。 这样的工作:
DelegatingConnection delConnection = new DelegatingConnection(dbcpConnection);
oraConnection = (oracle.jdbc.OracleConnection)delConnection.getInnermostDelegate();
不过这样一来返回oraConnection空指针:
DelegatingConnection delConnection = (DelegatingConnection) dbcpConnection;
oraConnection = (oracle.jdbc.OracleConnection)delConnection.getInnermostDelegate();
Answer 9:
下面的工作来解决AQ的TopicConnection.getTopicSession => JMS-112
//DEBUG: Native DataSource : weblogic.jdbc.common.internal.RmiDataSource
con = DataSource.getConnection();
debug("Generic SQL Connection: " + con.toString());
//DEBUG: Generic Connection: weblogic.jdbc.wrapper.PoolConnection_oracle_jdbc_driver_T4CConnection
if (con != null && con.isWrapperFor(OracleConnection.class)) {
WebLogicNativeJdbcExtractor wlne = new WebLogicNativeJdbcExtractor();//org.springframework to the rescue!!
java.sql.Connection nativeCon = wlne.getNativeConnection(con);
this.oraConnection = (OracleConnection) nativeCon;
debug("Unwrapp SQL Connection: " + this.oraConnection.toString());
}
//DEBUG: Native Connection: oracle.jdbc.driver.T4CConnection è
现在我可以在AQ-厂使用W / O JMS-112
Answer 10:
试图铸造象下面
WrappedConnectionJDK6 wc = (WrappedConnectionJDK6) connection;
connection = wc.getUnderlyingConnection();
文章来源: Connection cannot be cast to oracle.jdbc.OracleConnection