关于Hibernate之Unknown service requested [org.hibernate.cache.spi.RegionFactory]这个坑!

博主被Hibernate的坑困扰,新写的Service调用Dao出现问题,无论是否加@Service都会报错。国内网站说法不实,查看官网后发现是Controller中手动注入Service时ctx.close()导致,注释掉后问题解决,其他Controller自动注入则无此问题。

这几天频繁被一个Hibernate的坑困扰。明明这个Dao被很多个Service调用,为什么新写的一个Service调用总是出现如下问题:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.cache.spi.RegionFactory]
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	org.springframework.orm.hibernate5.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:151)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause

org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.cache.spi.RegionFactory]
	org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:184)
	org.hibernate.cfg.Settings.getRegionFactory(Settings.java:300)
	org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1322)
	org.hibernate.internal.SessionFactoryImpl.openSession(SessionFactoryImpl.java:677)
	org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:121)
	org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:692)
	com.supermap.zzsubcorp.iFacility.FacilityMetaDataEngine.dao.impl.FacilityServiceDaoImpl.getFacilityServices(FacilityServiceDaoImpl.java:82)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.lang.reflect.Method.invoke(Method.java:497)

进一步测试后发现,凡是这个Service调用任何Dao都会出现上面这个问题。更奇怪的是无论是在Service的Class头部加不加@Service都一样会报这个错。而国内的网站都说是因为Hibernate版本或配置的问题,纯属胡扯。。。。。。!

后来万般无奈查看Hibernate官网,才发现有外国大神跟我遇到过一样的问题。原因是我在Controller中注入Service时选择的是手动注入:

	public AccessControlCardController() {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("ApplicationContext*.xml");
		iIAccessControlCardService = (IAccessControlCardService)ctx.getBean("accessControlCardService");
		ctx.close();            //原因出在这里了,执行这句就会导致上述Hibernate错误
	}

看到了吧?把上面那行ctx.close();注释掉之后,一切问题都没有了,所有的Dao层调用都没有问题了。OMG!

现在翻回头来想想为什么其他Controller调用Service,Service再调用Dao就没问题?是因为其他的Controller里都是通过@Autowired的方式自动注入接口的,所以就避免了该问题。So dis nei!

老师说了,让我们在一个对象使用完毕后一定要记着释放,这到底是好习惯还是坏习惯!!!

<think>好的,我现在需要解决用户的问题:在Spring Boot中,EntityManagerFactory创建失败,具体原因是Hibernate无法找到EhCacheRegionFactory导致的异常。用户希望得到解决方法。我需要根据已有的知识和提供的参考信息来构建答案。 首先,我需要回忆一下Spring Boot和Hibernate整合EhCache的常见配置。通常,Hibernate使用EhCache作为二级缓存时,需要在配置文件中指定RegionFactory。常见的RegionFactory类是org.hibernate.cache.ehcache.EhCacheRegionFactory或者org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory,后者用于单例模式。 接下来,用户遇到的错误可能是由于Hibernate找不到这个RegionFactory类。这可能是因为依赖没有正确添加,或者配置参数有误。根据参考信息,用户可能没有正确引入EhCache的相关依赖。例如,可能需要添加hibernate-ehcache依赖,或者Spring Boot的缓存启动器。 然后,检查配置是否正确。在application.properties或application.yml中,需要设置hibernate.cache.region.factory_class属性为正确的类路径。同时,确保启用了二级缓存,即hibernate.cache.use_second_level_cache=true和hibernate.cache.use_query_cache=true。 另外,可能还需要在pom.xml或build.gradle中添加EhCache的依赖。例如,对于Maven项目,可能需要添加如下依赖: ```xml <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>对应版本</version> </dependency> ``` 或者,如果使用Spring Boot的starter,可能需要添加: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency> ``` 版本可能需要与Spring Boot的版本兼容,所以需要注意依赖的版本管理。 另外,检查是否有EhCache的配置文件,比如ehcache.xml,是否存在于类路径下(如src/main/resources目录)。如果配置文件缺失或配置错误,也可能导致RegionFactory初始化失败。 还需要考虑是否在Spring Boot的主类上添加了@EnableCaching注解,以启用缓存支持。 可能的错误原因包括: 1. 缺少EhCache相关依赖; 2. 配置中的RegionFactory类名拼写错误或路径不正确; 3. EhCache配置文件缺失或配置错误; 4. 未启用Hibernate的二级缓存; 5. 依赖版本冲突。 解决方法步骤可能包括: 1. 添加必要的依赖; 2. 检查并修正配置属性; 3. 添加或检查EhCache配置文件; 4. 确保启用二级缓存; 5. 处理版本兼容性问题。 另外,参考用户提供的引用内容,里面提到了spring-boot-loader模块支持可执行jar和war文件,但用户的问题可能与依赖管理或配置相关,所以可能需要检查构建工具(如Maven或Gradle)是否正确处理了依赖,特别是在生成可执行jar时是否包含所有必要的库。 最后,可能需要考虑是否使用了正确的Hibernate和EhCache版本组合,避免版本不兼容导致的类找不到问题。</think>要解决Spring Boot中因Hibernate无法找到EhCacheRegionFactory导致`EntityManagerFactory`创建失败的问题,需按以下步骤排查和修复: --- ### 1. **添加必要的依赖** 确保项目中包含`hibernate-ehcache`和`ehcache`的依赖: ```xml <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.6</version> <!-- 或与Spring Boot兼容的版本 --> </dependency> ``` 如果使用Spring Boot Starter: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> ``` --- ### 2. **配置Hibernate属性** 在`application.properties`中明确指定RegionFactory并启用缓存: ```properties # 启用Hibernate二级缓存 spring.jpa.properties.hibernate.cache.use_second_level_cache=true spring.jpa.properties.hibernate.cache.use_query_cache=true # 指定EhCache RegionFactory spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory # 可选:指定EhCache配置文件路径 spring.jpa.properties.hibernate.javax.cache.provider=net.sf.ehcache.CacheManager spring.jpa.properties.hibernate.javax.cache.uri=classpath:ehcache.xml ``` --- ### 3. **添加EhCache配置文件** 在`src/main/resources`目录下创建`ehcache.xml`(示例): ```xml <ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" diskSpoolBufferSizeMB="30" memoryStoreEvictionPolicy="LRU"/> </ehcache> ``` --- ### 4. **启用Spring缓存支持** 在Spring Boot主类或配置类上添加注解: ```java @EnableCaching @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` --- ### 5. **验证依赖版本兼容性** - **Spring Boot 2.x**:使用`ehcache 2.10.x`和`hibernate-ehcache 5.x`。 - **Spring Boot 3.x**:可能需要升级到Hibernate 6.x及对应缓存库。 --- ### 常见错误原因 - **依赖缺失**:未正确添加`hibernate-ehcache`或`ehcache`。 - **配置错误**:`hibernate.cache.region.factory_class`路径拼写错误。 - **文件缺失**:缺少`ehcache.xml`或路径配置不正确[^1]。 --- ### 相关问题 1. **如何验证Hibernate二级缓存是否生效?** 可通过日志检查`EntityManagerFactory`初始化时是否加载了EhCache配置。 2. **EhCache与Redis作为Hibernate缓存的区别?** EhCache是本地缓存,适合单机应用;Redis是分布式缓存,适合微服务场景。 3. **Spring Boot中如何动态更新EhCache配置?** 需通过`CacheManager` API重新加载配置或使用热部署工具[^1]。 [^1]: 参考Spring Boot官方文档关于缓存配置的说明。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值