一个简单的银行应用程序:
注意事项:
问题:
答案 0 :(得分:2)
使用EntityManager
注入的@PersistenceContext
实例是将实际工作委派给与当前交易相关联的EntityManager
的代理。
换句话说,它的工作原理如下:
@Transactional
范围时,将创建新事务并与当前线程相关联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>
基本概念:
- EntityManager - 管理实体的持久状态(或生命周期)的类。
- 持久性单元 - 是实体类的命名配置。
- 持久性上下文 - 是一组受管实体实例。实体类是持久性单元配置的一部分。
- 托管实体 - 如果实体实例是持久性上下文的一部分,并且实体管理器可以对其执行操作,则对其进行管理。
醇>
基于本文,您可以使用@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。
希望这有帮助。