spring 扫描 hibernate 的hbm.xml配置文件 特别慢的问题

程序散人 发布于 2014/02/21 11:30
阅读 4K+
收藏 0

在开发的一个项目中,遇到这样的一个问题

框架 SSH

hibernate的*.hbm.xml配置文件是由spring统一来扫描管理的。

代码如下:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">false</prop>
				<prop key="hibernate.format_sql">false</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<!-- hibernate 二级缓存开启 配置 -->
				<prop key="hibernate.cache.use_query_cache">true</prop>  
				<prop key="hibernate.cache.region_prefix">H3CACHE</prop>
				<prop key="cache.use_second_level_cache">true</prop>
				<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>
				<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
				<prop key="hibernate.generate_statistics">true</prop>
			</props>
		</property>
		<!-- 加载hibernate所有的配置文件 -->
		<property name="mappingDirectoryLocations">
			<list>
				<value>classpath:/com/bbb/smart/bean</value>
			</list>
		</property>
	</bean>
启动tomcat的时候spring会扫描hbm.xml文件,然后再解析,再进行类的映射,就会出现如下的情况

特别的慢,大概需要30秒甚至更长的时间

Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from file E:\tomcat7\webapps\ROOT\WEB-INF\classes\com\smart\www\bean\AboutUsBean.hbm.xml
    at org.hibernate.cfg.Configuration.addFile(Configuration.java:325)
    at org.hibernate.cfg.Configuration.addDirectory(Configuration.java:668)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:666)
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
    ... 42 more
Caused by: org.dom4j.DocumentException: Connection timed out: connect Nested exception: Connection timed out: connect
    at org.dom4j.io.SAXReader.read(SAXReader.java:484)
    at org.dom4j.io.SAXReader.read(SAXReader.java:264)
    at org.hibernate.cfg.Configuration.addFile(Configuration.java:311)
    ... 47 more

这时间应该消耗在了读取hbm.xml再进行映射的过程当中,有什么办法能够解决么?


以下是问题补充:

@程序散人:hibernate 的配置文件加载总会遇到这样的问题,在断开互联网之后,就会报如下的错误,难道hibernate加载的时候那个DTD是加载的互联网上的么? org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'newsDao' defined in ServletContext resource [/WEB-INF/springxml/spring-news.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/springxml/applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.InvalidMappingException: Could not parse mapping document from file E:\tomcat7\webapps\ROOT\WEB-INF\classes\com\smart\www\bean\city\CityBean.hbm.xml at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:275) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:104) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1245) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409) at java.security.AccessController.doPrivileged(Native Method) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380) at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1120) at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1678) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/springxml/applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.InvalidMappingException: Could not parse mapping document from file E:\tomcat7\webapps\ROOT\WEB-INF\classes\com\smart\www\bean\city\CityBean.hbm.xml at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409) at java.security.AccessController.doPrivileged(Native Method) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:269) ... 32 more Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from file E:\tomcat7\webapps\ROOT\WEB-INF\classes\com\smart\www\bean\city\CityBean.hbm.xml at org.hibernate.cfg.Configuration.addFile(Configuration.java:325) at org.hibernate.cfg.Configuration.addDirectory(Configuration.java:668) at org.hibernate.cfg.Configuration.addDirectory(Configuration.java:665) at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:666) at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335) ... 42 more Caused by: org.dom4j.DocumentException: Connection timed out: connect Nested exception: Connection timed out: connect at org.dom4j.io.SAXReader.read(SAXReader.java:484) at org.dom4j.io.SAXReader.read(SAXReader.java:264) at org.hibernate.cfg.Configuration.addFile(Configuration.java:311) ... 48 more (2014/02/21 14:48)
加载中
0
鱼北子
鱼北子
所有的XML映射文件都需要定义,如下所示的“DOCTYPE”: 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD  3.0 //EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping- 3.0 .dtd"> 

    该DTD定义将会根据不同的Hibernate版本而有所变化。默认情况下,处于XML文件解析效率的考虑,Hibernate在其二进制包hibernate3.jar的类路径"org/hibernate/"会存放一份DTD声明文件。 
    在Hibernate运行阶段,它首先会在Java运行时的类路径(CLASSPATH)下搜索DTD文件,然后再通过XML中的URL访问DTD定义。如果在开发过程中发现Hibernate在解析"*.hbm.xml"时消耗的时间过长时,就需要检查Hibernate是否通过网络来获取DTD文件,并查找Hibernate运行环境是否包含了DTD的定义文件。 
    Hibernate3.0的DTD文件位于: 
http:hibernate.sourceforge.net/hibernate-mapping-3.0.dtd 
开发者将Hibernate从版本2升级到3的时候,往往忽视DTD定义路径的修改,此时Hibernate初始化时导入"*.hbm.xml"非常慢,需要将2.0修改成3.0就不会有问题了。 
                                                ——《Hibernate ORM 最佳实践》
程序散人
程序散人
我用的是3.0的,和2.0没有关系的,网上的这个资料我已经找遍了。
0
鱼北子
鱼北子
<prop  key="hibernate.hbm2ddl.auto">update</prop>,update换为none肯定也会快一些。
0
大萌王朝首席槽点师
大萌王朝首席槽点师
根据你提供的文件来看, 我宁可相信时间被消耗在创建连接池,构建缓存上,hbmtoddl上  。在退一步讲,30s不算长。如果真的不爽,可以尝试去掉hbmtoddl
大萌王朝首席槽点师
大萌王朝首席槽点师
去掉hbmtoddl那个配置
程序散人
程序散人
能更详细一点儿么?
0
不二做
不二做
何不换成注解
程序散人
程序散人
换成注解就能带来启动速度上的提升?换成注解,只是少了读取配置文件那步了吧?
0
朱宏青
朱宏青
?占据启动时间30秒还长啊...我都不说我这个应用,服务器起的时候还算快,自己起一般都在5分钟左右...
程序散人
程序散人
额,那还怎么来开发啊。。
0
沈珈右
沈珈右

引用来自“dongqianlin”的答案

<prop  key="hibernate.hbm2ddl.auto">update</prop>,update换为none肯定也会快一些。

+1

去掉这个会是质的提升

0
鱼北子
鱼北子

引用来自“朱宏青”的答案

?占据启动时间30秒还长啊...我都不说我这个应用,服务器起的时候还算快,自己起一般都在5分钟左右...
30秒的确可以忍受,但是5分钟真有点久了,我一般把应用服务器的启动超时时间设置为120秒。
程序散人
程序散人
开发的时候难以忍受啊。
0
程序散人
程序散人
我到到问题的解决办法了 关键在于 hbm.xml里边DTD的路径要和hibernate jar包里的路径相匹配
0
鱼北子
鱼北子

引用来自“江湖看客”的答案

我到到问题的解决办法了 关键在于 hbm.xml里边DTD的路径要和hibernate jar包里的路径相匹配
嗯啊,我第一条回复就说的这个意思。
程序散人
程序散人
额,不好意思,当时看那个,我还以为是您想说 由于版本号不对应造成的问题的。研究了一下hibernate加载的过程,受益匪浅啊。谢谢你。
0
程序散人
程序散人

引用来自“dongqianlin”的答案

所有的XML映射文件都需要定义,如下所示的“DOCTYPE”: 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD  3.0 //EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping- 3.0 .dtd"> 

    该DTD定义将会根据不同的Hibernate版本而有所变化。默认情况下,处于XML文件解析效率的考虑,Hibernate在其二进制包hibernate3.jar的类路径"org/hibernate/"会存放一份DTD声明文件。 
    在Hibernate运行阶段,它首先会在Java运行时的类路径(CLASSPATH)下搜索DTD文件,然后再通过XML中的URL访问DTD定义。如果在开发过程中发现Hibernate在解析"*.hbm.xml"时消耗的时间过长时,就需要检查Hibernate是否通过网络来获取DTD文件,并查找Hibernate运行环境是否包含了DTD的定义文件。 
    Hibernate3.0的DTD文件位于: 
http:hibernate.sourceforge.net/hibernate-mapping-3.0.dtd 
开发者将Hibernate从版本2升级到3的时候,往往忽视DTD定义路径的修改,此时Hibernate初始化时导入"*.hbm.xml"非常慢,需要将2.0修改成3.0就不会有问题了。 
                                                ——《Hibernate ORM 最佳实践》

关键在于 hbm.xml里边DTD的路径要和hibernate jar包里的路径相匹配,即“http://hibernate.sourceforge.net/hibernate-mapping- 3.0 .dtd” 这个在hbm.xml和jar包里的dtd要完全匹配


http://hibernate.sourceforge.net/hibernate-mapping- 3.0 .dtd 这个DTD文件的路径可能会针对不同的版本号而有所不同,大家在出现这样问题的时候要注意这个问题。

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部