سؤال

Persistence units in persistence.xml are created during building the application. As I want to change the database url at runtime, is there any way to modify the persistence unit at runtime? I supposed to use different database other than pre-binded one after distributed.

I'm using EclipseLink (JPA 2.1)

هل كانت مفيدة؟

المحلول

Keep the persistence unit file (Persistence.xml) as it's. You can override the properties in it as follows.

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();

نصائح أخرى

You can use Persistence.createEntityManagerFactory(Map) to pass properties to choose the database URL and other settings.

In Long-lived Session Architecture you should create a Plug-in-Framework.

Therefore you need to create a different Thread-Group and Class-Repository.

This might be your Class-Loader-Tree

  • System-Class-Loader (usually a URLClassLoader, contains the Entitys)
    • JPA-Class-Loader
      • Load your jpa.jar with persistence.xml inside, specify the Database-Configuration from Application-Class-Loader
      • Instanciate your entityManager/session-factory.
      • Load any plugin you need to work with the DataBase. Execute Unit-Tests (;D) and Plugin-Integration-Tests.

If you are using Thorntail framework, you can wire-up the persistence.xml file to fetch runtime variables from "project-defaults.yml" file.

<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>

Take note of the dynamic DB values in ${...} as the point to values in the project-default.yml file.

Then you project-defaults.yml file will have an entry like this:

    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

I expect this should also work for Spring boot using application.properties and persistence.xml

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top