Spring4.1+Hibernate4.3报org.hibernate.cache.spi.RegionFactory或org.hibernate.engine.spi.CacheImplement

来源:互联网 发布:java图的深度优先遍历 编辑:程序博客网 时间:2024/05/15 18:12

Spring4.1+Hibernate4.3整合EhCache二级缓存设计报org.hibernate.cache.spi.RegionFactoryorg.hibernate.engine.spi.CacheImplementor的处理及细节问题说明

整合版本
spring-framework-4.1.0.RELEASE-dist
hibernate-release-4.3.6.Final

配置EhCache二级缓存时报错 - Unable to create requested service [org.hibernate.engine.spi.CacheImplementor]

这里可能会涉及到四个类
WEB项目容器启动时,报
- Unable to create requested service
[org.hibernate.engine.spi.RegionFactory]
org.hibernate.cache.spi.RegionFactory
或者
- Unable to create requested service
[org.hibernate.cache.spi.CacheImplementor]
org.hibernate.engine.spi.CacheImplementor

带[]的是不存在的,不带的是存在的类

详细的底层设计不多说了。

整了很久,答案五花八门。
最搞笑的一个答案,去用什么3的核心文件的cache部分进行替换,真是可笑。Hibernate3压根就没这个类。
真是不知所云。

个人喜欢在Spring中进行相关配置,并删除掉Hibernate的配置文件中的相关内容。想着可以对相关类实现更直观的参数信息注入和说明

先贴上Spring对ehcache的相关配置

    <bean id="ehCacheManagerFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">        <property name="configLocation">            <value>classpath:ehcache/ehcache.xml</value>        </property>    </bean>    <bean id="ehCacheCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">        <property name="cacheManager" ref="ehCacheManagerFactoryBean"/>    </bean>

结果此处蹩脚了,没有卵用,照样报错。

Spring4与Hibernate4整合之后启动JAVA项目就不多说了,
这里着重强调Java Web项目

以下详细分析和处理

1、关于hibernate.cache.provider_class配置说明

提供二级缓存的具体实现 - 【供应商】
hibernate.properties中可查,
默认为org.hibernate.cache.HashtableCacheProvider
- 是Hibernate核心包中的一个具体实现类

net.sf.ehcache.hibernate.EhCacheProvider

EhCacheProvider
- 在第三方包中有提供, - 在HIbernate自己的类中有具体的接口规范

经测试 - ***hibernate.properties中提供的相关的具体的实现类
在Hibernate的软件中都已经完成了实现的具体集成

不过,经测试发现,jar包是必须导入的
否则报下述类似的错误*

        java.lang.ExceptionInInitializerError        Caused by: org.hibernate.HibernateException: could not instantiate RegionFactory         Caused by: java.lang.reflect.InvocationTargetException        Caused by: java.lang.NoClassDefFoundError: net/sf/ehcache/CacheException        Caused by: java.lang.ClassNotFoundException: net.sf.ehcache.CacheException\
    <property name="hibernate.cache.provider_class">        3的版本 - org.hibernate.cache.EhCacheProvider        4的版本 - org.hibernate.cache.ehcache.EhCacheRegionFactory 或org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory    </property>

交给Spring - org.springframework.cache.ehcache.EhCacheManagerFactoryBean
在当前版本中是无效的

上述配置在H3中是必须的,在H4中是不必须的

2、关于hibernate.cache.region.factory_class 的配置
Hibernate4 想使用 ehcache 时做二级缓存时,
不使用 EHCache 提供的:hibernate.cache.region.factory_class
如,错误配置 -

    <property name="hibernate.cache.region.factory_class">        net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory    </property    报    nested exception is java.lang.No ClassDefFoundError:     org/hibernate/cache/EntityRegion

无视 EHcache 网站上的 document , 那是针对 Hibernate 3.X 的.

Spring内部本身有很多的配置就涵盖了Hibernate的配置信息
可以很灵活的完成参数注入
非常的强大
但是
单独配置Spring还是不行的 - 会报错
而且,后期加上Spring的配置也不行,照样报错。请看下述说明:
这就是约定。

Hibernate使用二级缓存 - 自身是重点
Hibernate 4.X 有自己对其他 Cache 框架的支持.
不加此项,无法使用二级缓存

在当前的Hibernate的配置文件中,
这个配置是必须的,否则
WEB项目容器启动时,报

- Unable to create requested service     [org.hibernate.engine.spi.RegionFactory]    org.hibernate.cache.spi.RegionFactory    或者    - Unable to create requested service     [org.hibernate.cache.spi.CacheImplementor]    org.hibernate.engine.spi.CacheImplementor    且不能配置为     - org.springframework.cache.ehcache.EhCacheManagerFactoryBean    此处无效    <property name="hibernate.cache.region.factory_class">        org.hibernate.cache.ehcache.EhCacheRegionFactory    </property>    可以配置为 -     org.hibernate.cache.ehcache.EhCacheRegionFactory    org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory

3、关于在Hibernate手动指定EhCache的配置文件信息的扩展配置说明

扩展配置为指定ehcache配置文件,
默认加载classpath下的:ehcache.xml

查看相关源码内容

net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory    - public class SingletonEhCacheRegionFactory extends AbstractEhcacheRegionFactory {public void start(Settings settings, Properties properties) throws CacheException {        configurationResourceName = (String) properties.get(NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME);    及    net.sf.ehcache.hibernate.EhCacheRegionFactory    - public class EhCacheRegionFactory extends AbstractEhcacheRegionFactory {public void start(Settings settings, Properties properties) throws CacheException {        configurationResourceName = (String) properties.get(NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME);    内部的提供的是    net.sf.ehcache.hibernate.AbstractEhcacheRegionFactory    - abstract class AbstractEhcacheRegionFactory implements RegionFactory {    的    /**    * The Hibernate system property specifying the location of the ehcache configuration file name.    * <p/>    * If not set, ehcache.xml will be looked for in the root of the classpath.    * <p/>    * If set to say ehcache-1.xml, ehcache-1.xml will be looked for in the root of the classpath.    */    public static final String NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME = "net.sf.ehcache.configurationResourceName";

查看源码得出的结论是,内部使用到了 - ehcache.xml,
而且全部都是在classpath寻找相关配置文件

我见网上有这样一个Hibernate配置文件中的配置项信息 - hibernate.cache.provider_configuration_file_resource_path
- 不知出处,只知其并没有任何作用
是无效配置项,是想当然。。是自我安慰罢了

而配置下述信息虽然有效,

<property name="net.sf.ehcache.configurationResourceName">/ehcache.xml</property>    但是在WEB环境初始化的时候会报错    nested exception is java.lang.NoSuchMethodError:     net.sf.ehcache.util.ClassLoaderUtil.getStandardClassLoader()    Ljava/lang/ClassLoader;

虽然从侧面证明起到了效果,但是没用

但是EHCACHE作为一个插件,本身没有设计的特别复杂,直接放在类路径下就可以了
只有这么一个文件,并不占地方

*在Hibernate配置文件中加了这一项之后,
就不能再在Spring中去配置别的了,
否则会产生冲突*,报Ehcache有两个初始化实例的错误,

Invocation of init method failed;     nested exception is net.sf.ehcache.CacheException:     Another unnamed CacheManager already exists in the same VM.     Please provide unique names for each CacheManager in the config or     do one of following:    1. Use one of the CacheManager.create() static factory methods to     reuse same CacheManager with same name or create one if necessary    2. Shutdown the earlier cacheManager before creating new one with same name.    The source of the existing CacheManager is: DefaultConfigurationSource     [ ehcache.xml or ehcache-failsafe.xml ]    Caused by: net.sf.ehcache.CacheException:     Another unnamed …… …… 

多个项目中多个sessionfactory使用hibernateehcache或者
hibernate和业务共同使用ehcache使用SingletonEhCacheRegionFactory

经查,ehcache在2.5以后,CacheManager使用了Singleton,
这样在创建多个CacheManager时就会产生上述错误。

所以此处,还是由Hibernate亲力亲为即可

    <property name="hibernate.cache.region.factory_class">        org.hibernate.cache.ehcache.EhCacheRegionFactory    </property>

OK,分析了这么多,上述代码就是暂时的结论,

如果使用的是EhCacheRegionFactory,项目跑起来之后,还会报 Unable to create requested service [org.hibernate.engine.spi.CacheImplementor]

证明二级缓存使用有误。

如果改为 - org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory

OK,不报上述错误了,但是,一波未平,一波又起。

又出现了
Could not obtain transaction-synchronized Session for current thread

关于这个错误的详细处理,篇幅较长,见下一篇文章。

上述结论补充完整的话,如下

    <!--         开启二级缓存        在hibernate.properties中可查,默认为false - 被禁用    -->    <property name="hibernate.cache.use_second_level_cache">        true    </property>    <!--     在Java Web项目中,必须是 -     org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory     -->    <property name="hibernate.cache.region.factory_class">        org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory    </property>    <!--  用于开启二级缓存的统计机制 -->    <property name="hibernate.generate_statistics">true</property>    <!-- 启用查询缓存 -->    <property name="hibernate.cache.use_query_cache">true</property>

如需要转载
请注明文章出处
http://blog.csdn.net/MUXINGYE/article/details/54562264
谢谢~

0 0