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

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

Spring 2.0 增加了對 JPA 資料訪問標準的支援,包含了所有預期的標準 Spring 支援類。 Mark Fisher 有一篇很棒的帖子,介紹瞭如何使用這種新的支援。然而,我們一直被問到的一個問題是,為什麼有人會想要使用 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"/>

沒關係,但是我如何獲得 EnityManager?

這可能實際上是最酷的部分。 基本上,您只需透過新增 @PersistenceContext JPA 註解,以與您不使用 Spring 時完全相同的方式定義 DAO。

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 中注入一個 EnitityManager


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

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

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

程式碼

  • @Repository 用於異常轉換
  • @PersistenceContext 用於 EntityManager 注入
  • 普通的 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();
    }
}

配置

  • LocalEnityManagerFactoryBean 用於建立 EntityManagerFactory
  • JpaTransactionManager 用於管理 JPA 事務
  • <tx:annotation-driven /> 告訴 Spring 查詢 @Transactional
  • 您的 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 社群中所有即將舉行的活動。

檢視全部