1
I have my persistence.xml
configured for 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 BD may be located on another server and have different user and password.
How I do it automatically?
Current Multi 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);
}
}
What is the real need to perform automatically?
– Diego Filipe Pedro Santos
Programmers' workstations have their own mysql (localhost). Already on the production server mysql will be on another dedicated server. I don’t want to have to keep exchanging the connection data whenever I have to deploy the application.
– NilsonUehara
I don’t know how your deployment structure works, but here at the company, some files at deploy time are disregarded when it comes to getting up to production.
– Diego Filipe Pedro Santos
@Diegosantos I have a Jenkins server that periodically checks the changes and builds the project. At some point the person responsible for updating the app takes this build and deploys it to the production server.
– NilsonUehara
The
JNDI
It’s nice when you let the container create the connection, because it simplifies. In this case you wrote code to create the connection, so you are already ready to get the parameters of a configuration file as I suggested in my reply. You may have a configuration file with the default information and devs change on your machine but don’t commit, or rather a filedev
and anotherprod
, Prod is renamed and included in the distribution package during continuous integration while thedev
is ignored. But I would do this with a file apart frompersistence.xml
.– Caffé