dao注入的sessionFactory和hibernateTemplate丟失

版本

整合SSH

struts版本: 2.5.14

spring版本: 5.0.3.RELEASE

hibernate版本: 5.2.13.Final

jdk版本: 1.8

數據庫使用MySql

現象:

IDEA整合SSH的時候:突然遇到dao下的getHibernateTemplate()爲null,

打入斷點後我發現HibernateDaoSupport的setSessionFactory()已被調用。spring 已注入sessionFactory,而繼承HibernateDaoSupport的HibernateDAO在當時存在hibernateTemplate。等到spring加載完applicationContext.xml之後,調用getHibernateTemplate()返回值卻爲null.

緣由:

花費大半天時間我才發現原來是<aop:pointcut>屬性設置的原因.我將切點匹配的範圍設置的太大了導致前面的dao的bean被重新裝配(sessionFactory未注入)

出錯的applicationContext.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
">

<!-- 自動掃描與裝配bean,包括子包 -->
<context:component-scan base-package="com.arthur.web.*"/>
<!-- 導入外部的properties文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!--配置數據源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<!--數據庫驅動類-->
<property name="driverClass" value="${driverClass}"/>
<!--數據庫連接URL-->
<property name="jdbcUrl" value="${jdbcUrl}"/>
<!--數據庫用戶名-->
<property name="user" value="${user}"/>
<!--數據庫用戶密碼-->
<property name="password" value="${password}"/>
<!--連接池最小保留個數-->
<property name="minPoolSize" value="5"/>
<!--連接池最大保留個數-->
<property name="maxPoolSize" value="30"/>
<!--初始化時獲得的連接數-->
<property name="initialPoolSize" value="10"/>
<!--最大空閒時間,爲0即永不連接-->
<property name="maxIdleTime" value="60"/>
<!--當連接池連接耗盡時,一次性獲取的連接數-->
<property name="acquireIncrement" value="5"/>
<!-- 控制數據源內加載的PreparedStatements數量。如果maxStatements與maxStatementsPerConnection均爲0,則緩存被關閉。Default:0 -->
<property name="maxStatements" value="8"/>
<!-- maxStatementsPerConnection定義了連接池內單個連接所擁有的最大緩存statements數。Default:0 -->
<property name="maxStatementsPerConnection" value="5"/>
<!--每60檢查連接池中所有的空閒連接-->
<property name="idleConnectionTestPeriod" value="60"/>
<!--和數據庫連接失敗後請求重新連接的次數-->
<property name="acquireRetryAttempts" value="30"/>
<!--連接失敗會通知等待的數據源連接放棄連接,數據源仍保留-->
<property name="breakAfterAcquireFailure" value="true"/>
</bean>

<!--定義Hibernate的SessionFactory -->
<!-- SessionFactory使用的數據源爲上面的數據源 -->
<!-- 指定了Hibernate的映射文件和配置信息 -->
<!--session工廠的配置-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!--爲session工廠注入數據源-->
<property name="dataSource" ref="dataSource"/>
<!--爲hibernate配置部分屬性-->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="show_sql">true</prop>
<prop key="format_sql">true</prop>
<prop key="hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/myweb</prop>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
</props>
</property>

<property name="mappingLocations">
<list>
<value>classpath:com/arthur/web/pojo/*.hbm.xml</value>
</list>
</property>
<property name="annotatedClasses">
<list>
<value>com.arthur.web.pojo.User</value>
</list>
</property>

</bean>

<!-- dao實例化 -->
<bean id="hibernateDAO" class="com.arthur.web.core.common.dao.HibernateDAO">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>


<!--配置事務管理-->
<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 配置事務增強 -->
<tx:advice id="txAdvice" transaction-manager="txManager" >
<tx:attributes>
<tx:method name="do*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>

<!-- 配置將通知織入目標對象-->
<aop:config>
<!-- 配置切點 -->
<aop:pointcut expression="execution(* com.arthur.web..*.*(..))" id="txPc"/>
<!--定義通知-->
<aop:advisor pointcut-ref="txPc" advice-ref="txAdvice"/>

</aop:config>

</beans>

解決方案:

當我將切點匹配範圍收縮到service範圍時候。dao恢復正常可以進行增刪改查

<aop:pointcut expression="execution(* com.arthur.web.service..*.*(..))" id="txPc"/>

待解決疑問:

爲啥 aop:pointcut 設置範圍過大的時候重裝配的dao未注入session.由於花費太長時間在這問題上,這疑問只能留到以後再處理了了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章