persistence.xml for development and another for production?

1

I have my persistence.xml set to a local database.

<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/meubanco"/>
<property name="hibernate.connection.username" value="usuario"/>
<property name="hibernate.connection.password" value="senha"/>

It turns out that the development and production environments should have different configurations, because in production the DB may be located on another server and have different user and password.

How do I do this automatically?

Current Tenancy Structure

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="onlinePU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>br.com.teste.model.Cliente</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3307/online"/>
      <property name="hibernate.connection.username" value="user"/>
      <property name="hibernate.connection.password" value="senha"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
      <property name="hibernate.show_sql" value="false"/>
      <property name="hibernate.format_sql" value="false"/>
      <!--Configuracao do Hibernate para MultiTenant-->
      <property name="hibernate.multiTenancy" value="SCHEMA"/>
      <property name="hibernate.tenant_identifier_resolver" value="br.com.teste.multitenant.SchemaResolver"/>
      <property name="hibernate.multi_tenant_connection_provider" value="br.com.teste.multitenant.MultiTenantProvider"/>
      <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
      <property name="hibernate.c3p0.acquire_increment" value="2"/>
      <property name="hibernate.c3p0.iddle_teste_period" value="70"/>
      <property name="hibernate.c3p0.max_size" value="5"/>
      <property name="hibernate.c3p0.max_statements" value="0"/>
      <property name="hibernate.c3p0.min_size" value="1"/>
      <property name="hibernate.c3p0.timeout" value="60"/>
    </properties>
  </persistence-unit>
</persistence>

MultiTenantProvider

public class MultiTenantProvider implements MultiTenantConnectionProvider, ServiceRegistryAwareService  {

    private static final long serialVersionUID = 4368575201221677384L;

    private C3P0ConnectionProvider connectionProvider = null;

    @Override
    public boolean supportsAggressiveRelease() {
        return false;
    }

    @Override
    public void injectServices(ServiceRegistryImplementor serviceRegistry) {
        Map lSettings = serviceRegistry.getService(ConfigurationService.class).getSettings();

        connectionProvider = new C3P0ConnectionProvider();
        connectionProvider.injectServices(serviceRegistry);
        connectionProvider.configure(lSettings);
    }

    @Override
    public boolean isUnwrappableAs(Class clazz) {
        return false;
    }

    @Override
    public <T> T unwrap(Class<T> clazz) {
        return null;
    }

    @Override
    public Connection getAnyConnection() throws SQLException {
        final Connection connection = connectionProvider.getConnection();
        return connection;
    }

    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
        final Connection connection = getAnyConnection();
        try {
            connection.createStatement().execute("use " + tenantIdentifier + ";");
        }
        catch (SQLException e) {
            throw new ClienteInvalidoException("Cliente inválido!");
        }
        return connection;
    }

    @Override
    public void releaseAnyConnection(Connection connection) throws SQLException {
        try {
            connection.createStatement().execute("use online;");
        }
        catch (SQLException e) {
            throw new ClienteInvalidoException("Cliente inválido!");
        }
        connectionProvider.closeConnection(connection);
    }

    @Override
    public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
        releaseAnyConnection(connection);
    }
}
    
asked by anonymous 14.10.2014 / 15:14

2 answers

1

If I understand you, you want dynamic bank access using a multi-tenant architecture. There are several exits.

I would personally use Spring to set different profiles as dev , uat and prod .

Then you could set different versions of EntityManagerFactory or one single version initialized via properties files specific to each environment.

A more "manual" approach is to generate WAR or EAR packages for different ones for different environments. This is very easy with Maven.

It would also be possible to define different persistence units and use each one according to the environment. This can be done by instantiating EntityManagerFactory through the Persistence class. , because there is a version of the createEntityManagerFactory method that receives a String , which is the persistence unit name.

Another alternative is to use the same persistence unit , but pass a map with the user and password of each connection, loaded from some configuration file. This can be done through another version of the createEntityManagerFactory method of the Persistence class or the createEntityManager method of EntityManagerFactory already created.

    
14.10.2014 / 18:45
-1

persistence.xml is not a production configuration file. Although you can enter all database access details in this file, you should not do it for production use or approval - in these cases the database access configuration must be open to the role of "deployer" . , while the persistence.xml file is the responsibility of the developer role of the system.

Although the same person eventually takes these two roles, as this file belongs to the set of source code files and is distributed already configured, you would literally have a change in the system every time the environment changes (databases change from place, name, username and password also change).

If you use an application server ( Glassfish , for example), set up bank access using JNDI feature. If not, consider putting the access information to the bank in an encrypted configuration file.

    
14.10.2014 / 17:47