动态更改持久化单元 - JPA

19

persistence.xml 中的持久化单元是在构建应用程序时创建的。我想在运行时更改数据库的URL,有没有办法在运行时修改持久化单元?我打算在分布后使用不同的数据库而不是预先绑定的数据库。

我正在使用 EclipseLink (JPA 2.1)


1
你使用任何服务器吗? - Grim
不是的。它是独立应用程序。数据库服务器是Oracle-12c和SQL Server 9.0.x。 - N K
4个回答

38

保留持久化单元文件(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();

有没有办法在内存中动态创建多个持久化单元? - meadlai
持久化的包? - afe

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

0
在长期会话架构中,您应该创建一个插件框架。
因此,您需要创建不同的线程组和类存储库。
这可能是您的类加载器树
  • 系统类加载器(通常是URLClassLoader,包含实体)
    • JPA类加载器
      • 使用内部的persistence.xml,指定来自应用程序类加载器的数据库配置,加载您的jpa.jar
      • 实例化您的entityManager/session-factory。
      • 加载任何您需要与数据库一起使用的插件。执行单元测试(;D)和插件集成测试。

0
如果您正在使用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 Boot。


但是这在“运行时”是如何实现的呢?它仍然是在源代码/二进制文件中预先绑定的。 - fundagain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接