在 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 社区所有即将举行的活动。

查看所有