【问题标题】:Changing Persistence Unit dynamically - JPA动态更改持久性单元 - JPA
【发布时间】:2013-09-06 04:36:41
【问题描述】:

persistence.xml 中的持久性单元是在构建应用程序期间创建的。由于我想在运行时更改数据库 url,有没有办法在运行时修改持久性单元?我应该在分发后使用不同的数据库而不是预先绑定的数据库。

我正在使用 EclipseLink (JPA 2.1)

【问题讨论】:

  • 您使用任何服务器吗?
  • 没有。它是独立的应用程序。数据库服务器是 Oracle-12c 和 SQL Server 9.0.x

标签: java jpa persistence.xml


【解决方案1】:

如果您使用的是 Thorntail 框架,您可以连接 persistence.xml 文件以从“project-defaults.yml”文件中获取运行时变量。

<persistence-unit name="java:jboss/datasources/my-postgres-ds">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>com.package.jpa.EntityClass1</class>
    <class>com.package.jpa.EntityClass2</class>
    <class>com.package.jpa.EntityClass3</class>
    <properties>
        <property name="hibernate.archive.autodetection" value="class"/>
        <property name="hibernate.show_sql" value="true"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>


        <property name="hibernate.connection.url"
                  value="${thorntail.datasources.data-sources.my-postgres-ds.connection-url}"/>
        <property name="hibernate.connection.username"
                  value="${thorntail.datasources.data-sources.my-postgres-ds.user-name}"/>
        <property name="hibernate.connection.password"
                  value="${thorntail.datasources.data-sources.my-postgres-ds.password}"/>


        <property name="hibernate.default_schema" value="public"/>
        <property name="hibernate.hbm2ddl.auto" value="update"/>
    </properties>

</persistence-unit>

记下 ${...} 中的动态数据库值作为指向 project-default.yml 文件中的值。

然后你的 project-defaults.yml 文件将有一个这样的条目:

    thorntail:
       http:
         port: 8989
       datasources:
          data-sources:
             my-postgres-ds:
                driver-name: my-postgres-driver
                connection-url: "jdbc:postgresql://localhost:5432/my-db-name"
                user-name: my-user-name
                password: "my-password#"
          jdbc-drivers:
             my-postgres-driver:
                driver-module-name: org.postgresql
                driver-xa-datasource-class-name: org.postgresql.xa.PGXADataSource

我希望这也适用于使用 application.properties 和 persistence.xml 的 Spring 启动

【讨论】:

  • 但是“在运行时”是怎么回事?它仍然预先绑定在源/二进制文件中。
【解决方案2】:

保持持久性单元文件 (Persistence.xml) 不变。您可以按如下方式覆盖其中的属性。

EntityManagerFactory managerFactory = null;
Map<String, String> persistenceMap = new HashMap<String, String>();

persistenceMap.put("javax.persistence.jdbc.url", "<url>");
persistenceMap.put("javax.persistence.jdbc.user", "<username>");
persistenceMap.put("javax.persistence.jdbc.password", "<password>");
persistenceMap.put("javax.persistence.jdbc.driver", "<driver>");

managerFactory = Persistence.createEntityManagerFactory("<current persistence unit>", persistenceMap);
manager = managerFactory.createEntityManager();

【讨论】:

【解决方案3】:

您可以使用 Persistence.createEntityManagerFactory(Map) 传递属性以选择数据库 URL 和其他设置。

【讨论】:

    【解决方案4】:

    在长寿命会话架构中,您应该创建一个插件框架。

    因此您需要创建不同的线程组和类存储库。

    这可能是你的类加载器树

    • System-Class-Loader(通常是 URLClassLoader,包含实体)
      • JPA 类加载器
        • persistence.xml 加载你的jpa.jar,从Application-Class-Loader 指定Database-Configuration
        • 实例化您的 entityManager/session-factory。
        • 加载使用数据库所需的任何插件。执行单元测试 (;D) 和插件集成测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-25
      • 2021-02-17
      • 2012-07-26
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      • 2013-04-18
      • 2014-03-28
      相关资源
      最近更新 更多