在 Spring 中使用 JPA,而無需引用 Spring

工程 | Ben Hale | 2006年8月7日 | ...

Spring 2.0 增加了對 JPA 資料訪問標準的支援,並提供了所有您期望的標準 Spring 支援類。Mark Fisher 釋出了一篇關於如何在 Spring 2.0 中使用此新支援的精彩博文。然而,我們經常收到的一個問題是,為什麼有人會想使用 Spring 類(JpaTemplate)來訪問 EntityManager。這個問題的最佳答案在於 JpaTemplate 提供的增值功能。除了提供 Spring 資料訪問的標誌性單行便利方法外,它還提供了自動參與事務和將 PersistenceException 轉換為 Spring DataAccessException 層次結構的功能。

但我仍然不想使用 JpaTemplate

沒關係,因為您不必犧牲 Spring 的強大功能。具體來說,最大的兩個優勢(事務參與和異常轉換)無需編寫針對 Spring 類的程式碼即可獲得。事實上,Spring 對純 API DAO 提供了廣泛的支援。

事務參與

Spring 宣告式事務管理的一個好處是,您永遠不需要在程式碼中引用事務結構。因此,如果您想要自動事務參與,您只需要幾個 bean 定義。

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" />

<bean class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<tx:annotation-driven />

JpaTransactionManager 負責建立 EntityManager、開啟事務並將其繫結到當前執行緒上下文。 <tx:annotation-driven /> 只是告訴 Spring 將事務性建議應用於任何帶有 @Transactional 註釋的類或方法。您現在可以只編寫您的主線 DAO 邏輯,而無需擔心事務語義。


public Collection loadProductsByCategory(String category) {
    return entityManager.createQuery("from Product p where p.category = :category")
        .setParameter("category", category).getResultList();
}

異常轉換

如果您想要 Spring 的異常轉換,也可以實現。所有需要做的就是在您的類上引入 @Repository 註釋。這個(非常小的)Spring 註釋只是告訴 Spring 容器該類是一個持久化儲存庫,需要對其進行異常轉換。要實現異常轉換,需要一個簡單的 bean 定義。

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

好的,但我如何獲得 EntityManager?

這可能是最酷的部分。基本上,您只需像未使用 Spring 一樣定義 DAO,方法是在類上新增 @PersistenceContext JPA 註釋。

public class ProductDaoImpl implements ProductDao {

    private EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this. entityManager = entityManager;
    }

    public Collection loadProductsByCategory(String category) {
        return entityManager.createQuery("from Product p where p.category = :category")
            .setParameter("category", category).getResultList();
    }
}

透過新增一個 bean 定義,Spring 容器將充當 JPA 容器,並從您的 EntityManagerFactory 注入一個 EntityManager


<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

這麼長的帖子肯定意味著大量的程式碼和配置

但事實並非如此!既然我們已經展示了所有零散的部分,讓我們來看看完整的系統。

程式碼

  • 用於異常轉換的 @Repository
  • 用於 EntityManager 注入的 @PersistenceContext
  • 純 JPA API 程式碼!

@Repository
public class ProductDaoImpl implements ProductDao {

    private EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this. entityManager = entityManager;
    }

    public Collection loadProductsByCategory(String category) {
        return entityManager.createQuery("from Product p where p.category = :category")
            .setParameter("category", category).getResultList();
    }
}

配置

  • 用於建立 EntityManagerFactoryLocalEntityManagerFactoryBean
  • 用於管理 JPA 事務的 JpaTransactionManager
  • 用於告訴 Spring 查詢 @Transactional<tx:annotation-driven />
  • 您的 bean 定義!

<?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: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/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" />
	
    <bean id="productDaoImpl" class="product.ProductDaoImpl"/>

    <bean
        class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

    <bean class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory"
            ref="entityManagerFactory" />
    </bean>

    <tx:annotation-driven />
	
</beans>

就這樣。兩個註解和四個 bean 定義。

其他資源



已更新以從 bean 定義中刪除省略號。有關背景資訊,請參閱註釋。

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有