在 Spring 中使用 JPA 而不參考 Spring

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

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 社群中所有即將舉行的活動。

檢視全部