将java.sql.Connection转换为com.mysql.jdbc.Connection

3

我的数据库使用MySQL,我使用hibernate作为ORM框架。我有一个需要访问MySQL Connection对象的实例。我使用以下代码获取java.sql.Connection对象:

getHibernateTemplate().getSessionFactory().getCurrentSession().connection();

然而,当我试图将其转换为 (com.mysql.jdbc.Connection) 对象时,我会收到以下异常:
java.lang.ClassCastException: $Proxy50 cannot be cast to com.mysql.jdbc.Connection

奇怪的是,如果我执行conn.getClass().getName(),返回的类类型是"$Proxy50"而不是'java.sql.Connection'或其他有意义的类型。

从Hibernate中获取特定于供应商的Connection对象的正确方法是什么?(我正在尝试读取MySQL系统属性)。为什么我的上面的示例不起作用?


1
不确定Spring的HibernateTemplate起什么作用,但是可以尝试使用Connection#unwrap()方法。 - BalusC
做这件事要非常小心。 "原始" JDBC 连接通常在几个不同的类层之下,所有这些类都实现了连接。最常见的情况是连接池添加的一层,以便当您“关闭”连接时,您真正做的是将其返回到池中。如果您对原始连接执行某些由这些层跟踪的操作,则会有风险。请确保您需要这样做,而不是通过其他方式实现您的目标。 - rfeak
@BalusC - 不错的想法。我试过了,但我的版本的Apache DBCP连接池没有实现unwrap方法。当我尝试时,我得到了以下异常:java.lang.AbstractMethodError: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.unwrap(Ljava/lang/ClassLjava/lang/Object; - David
@rfeak - 我只是想读取MySQL allowNanAndInf属性的值(该属性确定是否允许在双精度字段中使用NaN值)。我不打算对供应商MySQL连接对象执行任何查询或插入/更新操作。 - David
DBCP确实不符合JDBC4标准。如果可以的话,请更换它。反正这个连接池很糟糕。另请参见https://dev59.com/pXRB5IYBdhLWcg3wxZ1K#3481821。 - BalusC
3个回答

1
通常情况下,您不需要访问具体的Connection实现。
但是如果您真的非常需要,这里有一个解释:$Proxy40表示它是一个JDK动态代理。Spring倾向于创建这些代理。如果您的代理是由Spring创建的,那么您可以通过以下方式获取真正的对象:
Advised advised = (Advised) connection;
Connection conn = (Connection) advised.getTargetSource().getTarget();

如果Spring没有涉及代理,你应该能够像BalusC建议的那样调用Connection.unwrap(..)(无论哪种方式都可以)。

我正在使用Spring,所以我尝试了你的代码示例,但是出现了以下异常:java.lang.ClassCastException: $Proxy50无法转换为org.springframework.aop.framework.Advised。 - David
如果代理对象没有被Spring创建,那么可能会出现这种情况。您尝试过使用.unwrap(..)方法吗? - Bozho

0
获取Hibernate中特定供应商的Connection对象的正确方法是什么?
这要看情况而定。
我已经成功地解开了代理,就像这样。 如何从动态代理中解开原始对象 有点可怕,如果可以的话,最好避免使用。

0

com.mysql.jdbc.Connection 实现了 java.sql.Connection 接口。因此,当您创建 com.mysql.jdbc.Connection 对象时,它也是一个 java.sql.Connection 对象。所以您不能进行强制类型转换操作,因为返回的对象是 java.sql.Connection 而不是 com.mysql.jdbc.Connection


1
你需要了解向下转型,这正是这种操作。它很危险,因为就像原帖子中的问题一样,如果你不知道Connection的确切类型,你可能会遇到ClassCastException。在这种情况下,对象是java.sql.Connection类型,只是它不直接是com.mysql.jdbc.Connection类型。 - ig0774

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接