`
fox.tan
  • 浏览: 63266 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

ConnectionWrapper is not visible from class loader

阅读更多

 

    整合Spring DM(OSGi) 和 Hibernate 时出现了一些异常:
java.lang.IllegalArgumentException: interface org.hibernate.jdbc.ConnectionWrapper is not visible from class loader
    at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353)
    at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
    at org.hibernate.jdbc.BorrowedConnectionProxy.generateProxy(BorrowedConnectionProxy.java:91)
    at org.hibernate.jdbc.ConnectionManager.borrowConnection(ConnectionManager.java:186)
    at org.hibernate.jdbc.JDBCContext.borrowConnection(JDBCContext.java:134)
    at org.hibernate.impl.SessionImpl.connection(SessionImpl.java:386)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:507)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:336)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:102)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
 
      第一感觉这个异常是因为OSGi中的Class Loader的问题引起的,但跟踪code发现这个问题并不完全是因为Class Loader的问题。将Hibernate的hibernate.connection.release_mode propertie修改为after_transaction可以解决这个问题。

      但这个问题的根源在哪里呢?
 
    首先我来看看 HibernateTransactionManager.doBegin() 方法中的:
         ......
         if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
               // We're allowed to change the transaction settings of the JDBC Connection.
               //从Thread stack可以看到代码进入了这一行,也就是上面方法返回了true。
               Connection con = session.connection();
                ......
 

   
     isSameConnectionForEntireSession() 方法:
       
protected boolean isSameConnectionForEntireSession(Session session) {
             if (!(session instanceof SessionImpl)) {
                 // The best we can do is to assume we're safe.
                 return true;
             }
             ConnectionReleaseMode releaseMode = ((SessionImpl) session).getConnectionReleaseMode();
             //返回true,所以 releaseMode == ON_CLOSE
             return ConnectionReleaseMode.ON_CLOSE.equals(releaseMode);
         }
 
    但是是什么决定releaseMode呢?
    进一步跟踪发现releaseMode是Hibernate SessionFactory在创建Session的时候传入的,但SessionFactory中的
releaseMode 又是从哪来的呢?原来在 Spring中如果 hibernate.connection.release_mode设置成默认值auto时,在 transaction模式下会读取SpringTransactionFactory的getDefaultReleaseMode值 ON_CLOSE,参考:
  
            // Sets connection release mode "on_close" as default.
           // <p>This was the case for Hibernate 3.0; Hibernate 3.1 changed
           // it to "auto" (i.e. "after_statement" or "after_transaction").
           // However, for Spring's resource management (in particular for
           // HibernateTransactionManager), "on_close" is the better default.
            public ConnectionReleaseMode getDefaultReleaseMode() {
                 return ConnectionReleaseMode.ON_CLOSE;
           }
 因此,Hibernate使用默认的hibernate.connection.release_mode 设置'auto'时Session的Release Mode是ON_CLOSE。而在Transaction模式下明显是不对的,因此在properties中明确指定release_mode为 after_transaction是明智的。




分享到:
评论

相关推荐

    ConnectionPooljar数据连接池文件包的制作流程模板.doc

    2. 在工程内新建class文件, 文件的包起名为ConnectionPool。 3. 依次新建下列文件:ConnectionPool.java、 ConnectionWrapper.java、 LogFile.java、 LogWriter.java、 MakeDateTime.java、 PoolManager.java。 4. ...

    Java数据库通用层源码DBPool_v4.8.3_src

    - `ConnectionWrapper`:对原始数据库连接进行包装的类,添加额外的功能,如连接池的追踪和管理。 通过分析这个源代码,开发者可以深入理解数据库连接池的工作原理,学习如何实现自定义的数据库连接池,或者根据...

    ConnectionPooljar数据连接池文件包的制作计划流程.doc

    - ConnectionWrapper.java:用于封装数据库连接,提供统一的接口。 - LogFile.java和LogWriter.java:用于日志记录,跟踪连接池的使用情况。 - MakeDateTime.java:处理日期和时间的工具类。 - PoolManager.java...

    druid-1.1.6 源码包

    1. ConnectionWrapper:Druid对JDBC的Connection接口进行了封装,实现了连接池的特性,如连接的获取、释放、检测等。 2. DataSource:作为数据源的核心类,DruidDataSource提供了连接池的初始化、配置以及连接的...

    自己写的数据库连接池(全)

    - **ConnectionWrapper类**:包装原始的数据库连接对象,添加额外的监控和管理功能。 - **PoolConfig类**:存储连接池的配置参数,如最大连接数、最小连接数、超时时间等。 - **连接获取方法**(如getConnection())...

    蓝凌JAVA产品V16开发手册

    - 当需要获取数据库连接时,应通过`ConnectionWrapper`类实现,且使用完毕后记得关闭连接。 - **HQL查询语句问题定位**: - 遇到HQL语法错误时,可访问特定URL(如`http://localhost:8080/ekp/trans/to_sql?hql=你...

Global site tag (gtag.js) - Google Analytics