分类 JavaWeb 下的文章

Hibernate 5.1.1 + Spring 4.2.9 + Proxool 0.8.3 踩坑记录


起因

折腾的原因完全来自于我不想把DataSource配置到Spring的ApplicationContext中去.
希望Hibernate能够单独用一个配置文件, 这样就可以脱离Spring单独调试数据库部分的代码.

前提

原本在Spring 3.x + Hibernate 2.x的条件下已经成功了, 但是迁移到新版本就产生了各种各样的神奇的坑.

第一个坑

在新版本的Hibernate中, 在不使用org.apache.commons.dbcp.BasicDataSource的情况下, 似乎是不能用内置的默认连接池的.
大概看了下, Proxool似乎性能比较好, 用的比较多于是打算用这货.

抄了下网上常见的配置, 大概是这样的:

        <property name="hibernate.connection.provider_class">org.hibernate.proxool.internal.ProxoolConnectionProvider</property>
        <property name="hibernate.proxool.pool_alias">DBPool</property>
        <property name="hibernate.proxool.properties">test.properties</property>

可是...并不能找到配置文件, 从Trace一层一层网上看, 似乎是不知道传进去的路径是什么类型...
想了想, 加了file://可是依然不行= =
翻了好久源码, 突然看到...这货好像是从classpath开始搜索的...
放在classpath下果然就行了= =

第二个坑

Caused by: org.hibernate.service.UnknownUnwrapTypeException: Cannot unwrap to requested type [javax.sql.DataSource]

因为我把数据源配置在proxool里面, 所以明面上并没有给HibernateTransactionManager显式地传数据源...
可是HibernateTransactionManager在初始化的时候发现没有数据源会非常执着的去拿数据源, 拿不到还会去找ContentProvider要...可是并不能unwrap到数据源于是就报错了...
解决也很简单, HibernateTransactionManager有一个叫做autodetectDataSource的属性, 将其改为false即可.

第三个坑

其实算是我自己作死...
因为为了省事我把MVC和Spring的ApplicationContext写在一起了...
然后proxool会报错说配置文件已经配置...[md不能智能一点么]
想了想之前看的Spring文档, 好像Spring的Application和MVC并不是同一个Context.
又看了下web.xml...好像在ServletContext和Servlet的init-param里面指定了两遍...
于是把sessionFactory单独拿出来放在Application的Context配置里就可以了= =

第四个坑

这个也是很迷...看之前的书, 他告诉我Hibernate的current_session_context_class属性应当设置为thread.
我也就照着做了...可是我在执行任何操作的时候都会和我说Transcation没有ACTIVE???
追踪到TransacationManager里去也发现这里面的Transcation也正常的ACTIVE了.
可是执行的时候却拿不到ACTIVE过的session???
认真看了源码...好像它每次执行数据库操作的时候都是从Factory生成一个Session然后就去执行了...EXECUSE ME???
TransacationManger管理的Session呢???
查了好久发现...这篇文章难怪= =拿不到TransacationManger管理的Session啊_(:_」)_

配置了<property name="current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>马上就好了(╯‵□′)╯︵┻━┻