最近小編學習了Spring JPA相關的知識,spring提供的JPA十分方便,於是在自己已有的項目中嘗試了相關技術,原項目中已經配置了hibernate,現又添加JPA我的配置如下:
<?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:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/music"/>
<property name="user" value="root"/>
<property name="password" value="znck12345"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list><!-- 指定映射類 -->
<value>com.wxj233.music.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop> <!-- 指定hibernate是否要根據持久化類自動建立數據表 -->
<prop key="hibernate.show_sql">false</prop> <!-- 顯示Hibernate持久化操作所生成的SQL -->
<prop key="hibernate.format_sql">true</prop> <!-- 將SQL腳本進行格式化後再輸出 -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop><!-- 指定數據庫方言 -->
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop><!-- 排除掉數據庫可能不支持的功能 -->
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean><!-- 事務管理器 -->
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<jpa:repositories base-package="com.wxj233.music.repository"/><!-- 掃描繼承JpaRepository接口類 -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.wxj233.music.entity" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="generateDdl" value="true" />
<property name="showSql" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
</bean>
</property>
</bean>
</beans>
我可看到我在項目中配置了“hibernateTransactionManager”與“jpaTransactionManager”兩個管理器
我的事物支持配置如下:
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/> <!-- 事務管理支持,默認使用"transactionManager" -->
按此運行系統出現錯誤
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'transactionManager' available: No matching PlatformTransactionManager bean found for qualifier 'transactionManager' - neither qualifier match nor bean name match!
可以看到我明明設置了transaction-manager="hibernateTransactionManager",但系統仍然報找不到bean“transactionManager”的錯誤,“transactionManager”是系統默認使用的事務管理器名稱,即transaction-manager不配置的情況下默認使用名稱爲transactionManager的管理器,註解“@Transactional”處均使用transaction-manager所配置的事務管理器,但官方文檔中有這樣一句話
@EnableTransactionManagement和< tx:註解驅動/ >查找@ transactional只在bean在同一應用程序上下文定義它們。這意味着,如果你把註解驅動的配置在WebApplicationContext DispatcherServlet,它檢查@ transactional bean只在你的控制器,而不是你的服務。有關更多信息,請參見MVC。
寫的很清楚,我的項目是直接配置的DispatcherServlet,掃描的包僅包含自己項目下的相關類,而JPA
的JpaRepository接口並不在我所掃描的包中,小編猜想也並不在一個上下文中,故而transaction-manager配置對spring中JpaRepository接口的實現類並不會生效。查看spring源碼可以發現spring JPA中存在很多@ transactional註解的類,那麼調用這些類時只會只用默認“transactionManager”的事務管理器,若你配置的事務管理器中沒有名稱爲“transactionManager”的bean那麼也就會報“transactionManager”找不到的錯誤了。
相關參考鏈接如下:
spring集成JPA的三種方法配置 - ihic11 - 博客園
spring - org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter ERROR - Stack Overflow
spring-data-book/application-context.xml at master · spring-projects/spring-data-book · GitHub