JPA 应用程序管理的持久性上下文数据源配置 java 没有持久性 xml 文件

JPA application managed persistence context data source configuration with java without persistence xml file

JPA 规范定义了两种配置和使用方式:

  1. 应用程序管理的持久性上下文
  2. 容器管理的持久性上下文

使用应用程序管理的持久性上下文方法,应用程序代码直接使用 EntityManagerFactory 创建 EntityManager。使用容器管理的持久性上下文,容器负责此。

似乎这一切都只与控制 EntityManager 个实例(创建、销毁等)有关。

问题是。为什么我们在PersistenceProviderclass中有两种不同的方法? (我的意思是使用不同的参数)

我是说这些:

  1. public EntityManagerFactory createEntityManagerFactory(String emName, Map map)
  2. public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map)

第一个似乎是应用程序托管类型。而且它只适用于 persistence.xml 文件,因为它只能采用持久性单元的名称。第二个是容器管理类型。它可以接受 PersistenceUnitInfo 对象。为什么我不能将应用程序托管类型与自定义 PersistenceUnitInfo 参数一起使用?无论如何,这两种变体似乎都适用于容器。差异仅出现在控制 EntityManager 个实例中。当我们谈论 EntityManagerFactory 的配置时,这个对象总是驻留在容器中,因为我可以用 @PersistenceUnit 注解注入它。

这看起来很奇怪,因为我仍然可以使用 <jta-data-source> 标记为应用程序托管类型指定数据源。我可以使用 java setter 方法对容器管理的类型执行相同的操作。如果我能做同样的事情,为什么我在一个变体中只能使用 XML 标签,而在第二个变体中我可以使用 java setter (java 配置)?

最典型的 JPA 案例

因此,此术语中的“容器”指的是 Java EE / Jakarta EE 容器(也称为“应用程序服务器”)。我认为这可能看起来如此令人困惑的原因是因为大多数文档都是针对典型的应用程序开发人员的,但是您询问的代码通常是 JPA 提供者和容器提供者的责任。

在大多数典型情况下,Java EE / Jakarta EE 容器中的应用程序 运行 不会使用这些 PersistenceProvider 方法。它可能会注入一个 EntityManager(容器管理的持久性上下文)或注入一个 EntityManagerFactory(应用程序管理的持久性上下文)。

PersistenceProvider#createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) 方法旨在让 JPA 提供程序允许 Java EE / Jakarta EE 容器创建 EMF,它可能用于容器管理和应用程序管理的持久性上下文。

并且在 Java SE 环境中,应用程序将调用 Persistence.createEntityManagerFactory(...),它会找到一个 Provider 并调用它的 PersistenceProvider#createEntityManagerFactory 方法。在这里,应用程序也不需要调用 PersistenceProvider 本身。

因此,如果您有一个典型的应用程序,并且您正试图找出要调用的 PersistenceProvider 方法,那么您可能走错了路,应该从一个更好的示例开始。

特殊情况

当您使用使用 persistence.xml 加载持久性上下文的典型方法时,这一切都很好,并且会为您处理,如前所述。但是,如果您的应用程序想要做一些不同的和自定义的事情,那么您就会进入可能想要自己调用 PersistenceProvider 的领域。例如。 this 是一篇稍微讨论这个主题的文章。您最终可能会使用这种方法将您的应用程序绑定到特定的提供商。

我不确定规范对这种情况的确切说明(如果有的话)。我会将其描述为具有更多“应用程序管理的持久性”的感觉,因为您肯定是自己创建 EntityManager,但我不确定这是否是正确或有用的描述。