Spring + JPA集成如何实际工作

时间:2014-06-23 08:20:01

标签: java spring jpa

一个简单的银行应用程序: enter image description here

注意事项:

  • 使用Spring + JPA和EclipseLink作为JPA提供程序实现
  • 使用@PersistenceContext
  • 将EntityManager注入BaseDaoImpl
  • DAO自动装入Service bean
  • 服务方法中使用的@Transactional注释

问题:

  1. 每个DAO是否都有自己的EntityManager实例或实例共享?
  2. 如果它们是单独的实例,那么交易如何运作?
  3. 如果共享实例,连接什么时候关闭?在应用程序关闭?这是否意味着,整个应用程序只有一个连接,不管DAO /实体的数量是多少,它在应用程序生命周期内是否开放?

3 个答案:

答案 0 :(得分:2)

使用EntityManager注入的@PersistenceContext实例是将实际工作委派给与当前交易相关联的EntityManager的代理。

换句话说,它的工作原理如下:

  • 当您输入@Transactional范围时,将创建新事务并与当前线程相关联
  • 当您在DAO中调用EntityManager的方法时,该调用将委派给与当前事务关联的EntityManager(如果不存在,则将创建新的EntityManager)< / LI>
  • 当您离开@Transactional范围时,交易将被提交,与之关联的EntityManager将被关闭

答案 1 :(得分:1)

使用@PersistenceContext向DAO注入的内容实际上不是底层ORM的实体管理器实现,而是将代理调用委托给它的Spring代理 实际的基础实体经理。代理的具体类通常是SharedEntityManagerInvocationHandler

底层实体管理器的范围通常是Spring托管事务的范围(另一个是扩展范围,这在这里是不可能的) Spring事务管理器(当JPA用作数据访问时通常为JpaTransactionManager)将EntityManager绑定到当前线程,随后从此处检索实体管理器,直到事务提交。对于新的交易,同样的事情发生了。 您可以查看JpaTransactionManager doBegin方法的源代码,这一切都会发生。

答案 2 :(得分:0)

根据您提供的解释,您使用带有EclipseLink的spring作为JPA提供程序,并且您可能正在使用J2EE容器作为您的Web应用程序,并且基于我的猜测我认为this 是关于工作原理的好文章。 / p>

基本概念:

  
      
  1. EntityManager - 管理实体的持久状态(或生命周期)的类。
  2.   
  3. 持久性单元 - 是实体类的命名配置。
  4.   
  5. 持久性上下文 - 是一组受管实体实例。实体类是持久性单元配置的一部分。
  6.   
  7. 托管实体 - 如果实体实例是持久性上下文的一部分,并且实体管理器可以对其执行操作,则对其进行管理。
  8.   

基于本文,您可以使用@PersistenceContext

来使用Container Managed EntityManager
  

当应用程序的容器(无论是Java EE容器还是Spring等任何其他自定义容器)管理实体管理器的生命周期时,实体管理器称为容器管理。获取Container Managed EntityManager的最常用方法是在EntityManager属性上使用@PersistenceContext注释。

注射就像这样:

  

只要解析了@PersistenceContext创建的引用,就会返回一个事务范围实体管理器。

  

每次在实体管理器上调用操作时,容器代理(容器在实例化时都会在实体管理器周围创建代理)检查JTA事务上的任何现有持久性上下文。如果找到一个,则实体管理器将使用此持久性上下文。如果它找不到,那么它将创建一个新的持久化上下文并将其与事务相关联。

因此,实体经理的生命周期由您的容器和

管理
  

我们使用EntityManager的实例,EntityManager的唯一作用是确定持久性上下文的生命周期。它在决定持久化上下文应该如何表现方面没有任何作用。重申一下,持久化上下文是一组受管实体实例。每当事务开始时,持久性上下文实例都会与之关联。当事务结束(例如提交)时,将刷新持久性上下文并与事务取消关联。

简而言之,容器通过您提供的EntityManagerFactory实例化您的EntityManager并管理它的生命周期,但为您注入EntityManager的代理。 TransactionManager负责根据您提供的注释创建,提交和... tranaction,每当它开始事务时与其关联的PersistancecContext以及当tranasction结束时它将提交PersistenceContext的状态。 EntityManager使用PersistenceContext,如果没有提供,EntityManager会创建一个。 EntityManager是线程安全的,只要它不保持状态并且状态(PersistenceContext)附加到当前tranasction。

希望这有帮助。