PersistenceUnit vs PersistenceContext

Posted

技术标签:

【中文标题】PersistenceUnit vs PersistenceContext【英文标题】: 【发布时间】:2014-01-29 02:16:48 【问题描述】:

在几个项目中我已经成功使用

@PersistenceUnit(unitName = "MiddlewareJPA")
EntityManagerFactory emf;
...
EntityManager entityManager = emf.createEntityManager();

获取EntityManager 用于数据库连接,但几天前我试图将我的项目移动到Jboss EAP 6.2,但它无法创建EntityManager。我在谷歌上搜索它,发现我应该尝试将@PersistenceUnit 更改为

@PersistenceContext(unitName = "MiddlewareJPA")
private EntityManager entityManager;

获取EntityManager。它有效,但我不知道为什么。 PersistenceUnitPersistenceContext 之间有什么区别?各有什么优缺点?我们应该在哪里使用其中之一?

【问题讨论】:

考虑采用 CDI 规范(JEE 6 中的新特性)来执行依赖注入,这样您就有了一种更“通用”的方式来执行它,而不是一大堆 API/框架特定的注释。这并没有真正为 JEE 6 本身中的实体管理器注入提供开箱即用的支持,但是有记录的方法来处理它。 mastertheboss.com/cdi/cdi-and-jpa-tutorial 作为可用答案的补充:这是一篇非常有用的文章,也可以帮助回答 OP 的问题:JPA Concepts 【参考方案1】:

PersistenceUnit 注入 EntityManagerFactoryPersistenceContext 注入 EntityManager。通常最好使用PersistenceContext,除非您确实需要手动管理EntityManager 生命周期。

【讨论】:

但是如果我们有多个持久化单元,那么除了管理 EntityManagerFactory 还有其他方法吗? 要回答@raj240 的问题,我们可以使用相应持久性单元的名称@PersistenceContext(unitName = "MiddlewareJPA") 注入实体管理器【参考方案2】:

我不知道它在 Java EE 中是如何工作的,但是在 Spring 中,当您指定 @PersistenceContext 注释时,它会注入 EntityManager。它从哪里得到EntityManager?通过调用EntityManagerFactory.createEntityManager() 在整个应用程序生命周期内创建一个EntityManager 是错误的。因此,改为使用EntityManager 接口的特殊实现并直接实例化。它有一个对 real EntityManager 的内部可变线程本地引用。方法的实现只是将调用重定向到这个 real EntityManager。还有一个 servlet 监听器,在每个请求之前通过调用 EMF.createEntityManager() 获取 EM 并将其分配给特殊的 EM 的内部引用。此侦听器还通过在 real EM 上调用 getTransaction().begin().commit().rollback() 来管理事务。这是对已执行工作的非常简化的描述。而且我相信,JEE 容器和 Spring 做的事情一样。

一般情况下最好注入EntityManager,因为使用EntityManagerFactory@PersistenceUnit,您应该每次都手动创建/销毁EntityManager并管理事务。

【讨论】:

【参考方案3】:

通过@PersistenceContext获得的EntityManager被称为Container Managed EntityManager,因为容器将负责管理“EntityManager”。通过@PersistenceUnit/entityManagerFactory.createEntityManager()获得的EntityManager由开发者在应用程序中管理。 (例如管理EntityManager的生命周期,释放EntityManager获取的资源等)。

【讨论】:

以上是关于PersistenceUnit vs PersistenceContext的主要内容,如果未能解决你的问题,请参考以下文章

无法启动服务 jboss.persistenceunit:org.hibernate.service.UnknownServiceException

JPA Hibernate Persistence 异常 [PersistenceUnit: default] 无法构建 Hibernate SessionFactory

创建名为“entityManagerFactory”的bean时出错:[PersistenceUnit:默认]无法构建Hibernate SessionFactory

Wildfly/JBOSS 持久性错误 MSC000001:无法启动服务 jboss.persistenceunit

异常[PersistenceUnit: default] Unable to build Hibernate SessionFactory

JPA 2.0:自动将实体类*从不同的 jar* 添加到 PersistenceUnit