Spring載入Hibernate失敗:Error creating bean with name 'sessionFactory' defined in ServletContext... Null
阿新 • • 發佈:2019-01-07
昨天突然發現Spring載入Hibernate觸發NullPointerException 異常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/spring-config/spring-hibernate.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196) ..... Caused by: java.lang.NullPointerException at org.postgresql.jdbc.TypeInfoCache.getSQLType(TypeInfoCache.java:182) at org.postgresql.jdbc.TypeInfoCache.getSQLType(TypeInfoCache.java:178) at org.postgresql.jdbc.TypeInfoCache.requiresQuoting(TypeInfoCache.java:851) at org.postgresql.jdbc.PgDatabaseMetaData.getTypeInfo(PgDatabaseMetaData.java:2785) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.logicalcobwebs.proxool.ProxyDatabaseMetaData.intercept(ProxyDatabaseMetaData.java:60) at $java.sql.Wrapper$$EnhancerByProxool$$5b0813c3.getTypeInfo(<generated>) at org.hibernate.engine.jdbc.spi.TypeInfo.extractTypeInfo(TypeInfo.java:101) at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:163) at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206) at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1885) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1843) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928) at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372) at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454) at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:439) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ... 28 more
感覺相當鬱悶,因為不是第一天用啊,這個spring+hibernate的配置一直沒問題,後來花了兩個小時不斷查度娘和google,未果。心有不甘,開啟spring-hibernate.xml仔細看:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <!-- 配置hibernate的session factory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" destroy-method="destroy"> <!-- <bean id="sessionFactory" class="com.freestyle.common.spring.MyLocalSessionFactoryBean" destroy-method="destroy"> --> <property name="dataSource" ref="dataSource"></property> <property name="packagesToScan"> <!-- hibernate sessionFactory管理的類存放位置,自動裝載 --> <list> <value>com.alco.bms.entities</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop> <!-- 設定自動建立|更新|驗證資料庫表結構 --> <prop key="hibernate.hbm2ddl.auto">update</prop> <!-- 是否在控制檯顯示sql --> <prop key="hibernate.show_sql">true</prop> <!-- 是否格式化sql,優化顯示 --> <prop key="hibernate.format_sql">true</prop> <!-- 是否開啟二級快取 --> <prop key="hibernate.cache.use_second_level_cache">false</prop> <!-- 是否開啟查詢快取 --> <prop key="hibernate.cache.use_query_cache">false</prop> <!-- 資料庫批量查詢最大數 --> <prop key="hibernate.jdbc.fetch_size">100</prop> <!-- 資料庫批量更新、新增、刪除操作最大數 --> <prop key="hibernate.jdbc.batch_size">50</prop> <!-- 是否自動提交事務 --> <prop key="hibernate.connection.autocommit">false</prop> <!-- 指定hibernate在何時釋放JDBC連線 --> <prop key="hibernate.connection.release_mode">auto</prop> <prop key="hibernate.enable_lazy_load_no_trans">false</prop> <!-- <prop key="hibernate.use_sql_comments">true</prop> --> <prop key="log4j.logger.org.hibernate.type">TRACE</prop> </props> </property> </bean> <!-- 配置事務異常封裝 --> <bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> <!-- 定義事務管理 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <aop:aspectj-autoproxy proxy-target-class="true"/> <context:component-scan base-package="com.alco.bms.dao"/> <!-- 定義 Autowired 自動注入 bean --> <!-- <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> --> </beans>
在spring裡面配置LocalSessionFactoryBean,也就設定了3個屬性,發生NullPointerException應該就這三個其中一個是null值引發的吧,於是寫了一個殼MyLocalSessionFactoryBean是extends LocalSessionFactoryBean的,我在新類裡面除錯一下看傳進入的是不是null值:
將.sleep處都打上斷點,將spring-hibernate.xml裡面的sessionFactory類換成MyLocalSessionFactoryBean再除錯,發現傳進來的引數都不為null啊,這下傻了。package com.freestyle.common.spring; import java.util.Properties; import javax.sql.DataSource; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; import com.freestyle.utils.Util; public class MyLocalSessionFactoryBean extends LocalSessionFactoryBean { public void setDataSource(DataSource dataSource){ if (dataSource==null){ Util.sleep(100); } System.out.println(dataSource); super.setDataSource(dataSource); } public void setPackagesToScan(String ...packagesToScan){ if (packagesToScan==null){ Util.sleep(100); } System.out.println(packagesToScan); super.setPackagesToScan(packagesToScan); } public void setHibernateProperties(Properties hibernateProperties){ if (hibernateProperties==null){ Util.sleep(100); } System.out.println(hibernateProperties); super.setHibernateProperties(hibernateProperties); } public MyLocalSessionFactoryBean() { super(); // TODO Auto-generated constructor stub } }
後來再看Exception的細節,發現這行:at org.postgresql.jdbc.TypeInfoCache.getSQLType(TypeInfoCache.java:182), 說明可能是資料庫或jdbc驅動方面發生的exception,應該與spring/hibernate沒關係,於是將proxool.xml資料來源切換到另一伺服器(兩個伺服器的database結構一樣)再執行,居然沒事!!!
這有點不解,最後沒招了,只有懷疑jdbc驅動,因為用的是postgresql資料庫,伺服器是postgresql 9.4 64bit,jdbc驅動用的是postgresql-9.4.1208.jre6.jar,後來上postgresql官網下了postgresql-9.4.1209.jar 換上。 一切OK!!!
開始不相信,於是再換回版本號為1208的jar, 出exception,換1209的jar , OK!!
原來你是這樣的PostgreSQL 驅動啊!!!