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

查看全部