【问题标题】:Read Environment Variables in persistence.xml file在 persistence.xml 文件中读取环境变量
【发布时间】:2012-02-08 20:17:41
【问题描述】:

我想读取 persistence.xml 文件中的环境变量。

想法是我不希望从属性文件中读取我的数据库详细信息,因为获取属性文件覆盖发生了变化。相反,我想从环境变量中读取详细信息。

有没有办法达到这个标准。

我使用 Spring 3,我的独立应用程序将部署在 unix 机器上。

【问题讨论】:

  • 不应在您的 persistence.xml 中定义诸如主机名之类的数据库详细信息。使用 JNDI 查找并在应用程序服务器中定义具体的数据库参数...
  • 嗨,很抱歉,我在这里没有使用任何应用程序服务器,我正在运行独立应用程序,这就是为什么我需要在 persistence.xml 文件中硬编码数据库详细信息。
  • 您想从环境变量还是从 persistence.xml 获取数据库详细信息?看起来你说你想从两者中得到它们,但并不完全清楚......
  • @Rana:您在独立应用程序(没有任何应用程序服务器)中使用 EJB 3.0 的具体情况如何?
  • @Rana:Ups,对不起,你应该提到这一点。没有应用服务器的 EJB 3.0 并不常见......

标签: java jakarta-ee spring-mvc persistence ejb-3.0


【解决方案1】:

您可以通过提供 Map 来更新持​​久性单元中的属性(请参阅 this)。

方便地,环境变量可以作为 Map 检索(参见this)。

将两者放在一起,您可以使用环境变量动态更新持久性单元中的属性。

编辑:简单示例...

persistence.xml...

<persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
    <provider>
        oracle.toplink.essentials.PersistenceProvider
    </provider>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
        <property name="toplink.logging.level" value="INFO"/>
        <property name="toplink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
        <property name="toplink.jdbc.url" value="jdbc:oracle:thin:@myhost:l521:MYSID"/>
        <property name="toplink.jdbc.password" value="tiger"/>
        <property name="toplink.jdbc.user" value="scott"/>
    </properties>
</persistence-unit>

使用环境变量更新persistence.xml“默认”单元的代码...

Map<String, String> env = System.getenv();
Map<String, Object> configOverrides = new HashMap<String, Object>();
for (String envName : env.keySet()) {
    if (envName.contains("DB_USER")) {
        configOverrides.put("toplink.jdbc.user", env.get(envName)));    
    }
    // You can put more code in here to populate configOverrides...
}

EntityManagerFactory emf =
    Persistence.createEntityManagerFactory("default", configOverrides);

【讨论】:

  • 嗨,Zack,我不确定如何将 Map 提供给 persistence.xml。您能否为此提供一些示例代码。
  • 已上传示例 - 我通过谷歌搜索“persistence.xml”找到了一些不错的信息
  • 嗨 Zack,上面的代码要求我在每次创建 EntityManagerFactory 对象时覆盖环境变量。在这种情况下,如果我在需要更改的 10 个类中使用此 EntityManagerFactory。
  • 在这种情况下,您应该使用一个单独的类来进行覆盖。您可以将 EntityManagerFactory 从一个类返回到 10 个类,并且只需要维护一个类进行覆盖。
  • 谢谢!我已经通过覆盖属性以相同的方式实现了。
【解决方案2】:

我认为这不会涵盖通过注入创建的 EM。更糟糕的是,我认为通过 EMF 创建的 EM 只能是 EXTENDED(例如,相当于注释 @PersistenceContext(type = PersistenceContextType.TRANSACTION) 与 EXTENDED 相对),因此如果需要事务 EM,则必须使用注入。

我想知道是否可以在运行时物理重写persistence.xml 文件。问题之一是,能够重写文件(权限,能够在 META-INF 等中访问它),其次,在 JPA 第一次打开文件之前重写它(我认为这是第一次注入 EM字段实际上是由应用程序代码引用的)

【讨论】:

    【解决方案3】:

    You could use this working example.

    它从从 EntityManagerFactory 获得的 PersistenceUnitInfo 实例获取 persistence.xml 中定义的所有属性(通过使用 eclipseLink 特定实现)。这些属性被环境变量中定义的值替换。

    【讨论】:

      猜你喜欢
      • 2013-06-07
      • 1970-01-01
      • 2017-03-06
      • 2013-05-27
      • 2014-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多