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

查看全部