【问题标题】:How to "parameterize" JPA database instance in persistence.xml?如何在 persistence.xml 中“参数化”JPA 数据库实例?
【发布时间】:2011-03-01 05:46:30
【问题描述】:

我有一个利用 JPA 的 Java Web 应用程序。数据库实例在persistence.xml 文件中使用jta-data-source 标记指定。

我想在同一个(glassfish)服务器上部署 Web 应用程序的第二个副本,但指向不同的数据库实例。

实现这一目标的最佳方法是什么?我认为理想情况下,我想在战争之外放置一个persistence.xml 覆盖文件(在类路径的某个地方?)。我不确定将它放在哪里或如何以不会与我的其他实例冲突的方式定义它。我可以看到我们以这种方式(SaaS)托管了一些实例,我希望配置在部署的战争之外,这样它就不会成为维护问题。出于安全原因,不能在客户端之间共享数据库实例。

我确信这不是我们小组独有的问题。其他人用来解决此问题的最佳做法或解决方案是什么?

【问题讨论】:

  • 如果您有多个唯一的应用实例正在运行,为什么不直接更改第二个实例的 persistence.xml?
  • 每次构建时必须为每个实例手动执行此操作似乎是一个维护问题,我想要一个自动化的解决方案。

标签: java database configuration jpa glassfish


【解决方案1】:

更新:

http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html

不确定这是否可以在应用服务器中设置,但我会试一试。唯一让我担心的是范围的管理。容器沿着事务边界管理范围

//inject entity manager
@Inject("mySpecialEntityManager")
EntityManager em;

//then mark the actual factory method in the factory bean with    
@Produces("mySpecialEntityManager")

但是如何管理范围是个问题


2.2.2。引导

JPA 规范定义了一个引导程序来访问 EntityManagerFactory 和 EntityManager。引导类是 javax.persistence.Persistence,例如

Map configOverrides = new HashMap();

configOverrides.put("hibernate.hbm2ddl.auto", "create-drop");

EntityManagerFactory programmaticEmf =

Persistence.createEntityManagerFactory("manager1", configOverrides);

第一个版本相当于第二个带有空地图的版本。地图版本是一组优先于您的 persistence.xml 文件中定义的任何属性的覆盖。第 2.2.1 节“打包”中定义的所有属性都可以传递给 createEntityManagerFactory 方法,还有一些附加属性:

*

  javax.persistence.provider to define the provider class used
*

  javax.persistence.transactionType to define the transaction type used (either JTA or RESOURCE_LOCAL)
*

  javax.persistence.jtaDataSource to define the JTA datasource name in JNDI
*

  javax.persistence.nonJtaDataSource to define the non JTA datasource name in JNDI
*

  javax.persistence.lock.timeout pessimistic lock timeout in milliseconds (Integer or String)
*

  javax.persistence.query.timeout query timeout in milliseconds (Integer or String)
*

  javax.persistence.sharedCache.mode corresponds to the share-cache-mode element defined in Section 2.2.1, “Packaging”.

【讨论】:

    【解决方案2】:

    我猜你也已经在其他方面改变了副本? (例如ear文件的名称)

    如果您使用 ant 或 maven 等构建软件,您可以在 persistence.xml 中使用占位符,并通过使用不同的构建参数来创建不同的“副本”。

    例如用行家

    mvn clean install -DmyDatabaseName=db/somedb

    【讨论】:

    • 好的,听起来很酷。我需要在我的 persistence.xml 中放置什么作为文本替换的占位符?
    • 见下面 Pascal 的评论 :-)
    • 我必须找到一个解决方案来解决最初的问题,因为我必须管理不同位置的大约 500 台服务器,连接不同。还有什么想法,因为制造 500 场战争不是一个好主意:S
    【解决方案3】:

    我会打包两个版本的 webapp 并在各自的persistence.xmljta-data-source 元素中声明一个特定的数据源(我认为你不能将这个文件外部化,它应该在WEB-INF/classes/META-INF/persistence.xml 中)

    【讨论】:

    • 啊,我担心。随着应用程序的成熟、添加更多客户端和发布新版本(10 个客户端意味着 10 个单独的构建和部署周期,其中包含对持久性文件的更改),多次构建以进行简单的配置更改从维护的角度来看似乎很痛苦)。我使用 maven 构建和打包。你知道是否有一个 maven 插件能够生成多个战争,为每个配置采用适当的持久性 xml?
    • @Vinnie:我会使用filtering and profiles(并让我的 CI 引擎使用构建矩阵构建所有变体)。在 persistence.xml 中声明类似 <jta-data-source>${foo}</jta-data-source> 的内容,并使用 Maven 过滤值。
    【解决方案4】:

    如何将persistence.xml 存储在classes 目录的META-INF 文件夹中,然后在类路径中首先指定该文件夹?

    【讨论】:

      【解决方案5】:

      通过 spring,您可以在应用程序启动时覆盖 persistence.xml 设置,并从外部属性文件加载这些设置。

      http://www.summa-tech.com/blog/2009/04/20/6-tips-for-managing-property-files-with-spring/

      看看@darren 的回答:Spring + Hibernate + JPA

      【讨论】:

        【解决方案6】:

        这是我在 Java SE 环境中能够做到的:

        创建一个没有persistence.xml 文件的 .jar 文件。我手动创建了一个manifest.mf 文件,并在Class-Path: 中输入了“。”除了我需要的其他条目。

        在您安装软件的目录中,创建一个META-INF 目录并将persistence.xml 放入其中。它应该会被自动拾取。

        例如

          /my/install/dir/
                         META-INF/persistence.xml
                         foo.jar
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-08-28
          • 1970-01-01
          • 1970-01-01
          • 2013-10-10
          • 1970-01-01
          • 2019-01-06
          • 2014-02-04
          相关资源
          最近更新 更多