Multiple Databases
Broadleaf datasources
Broadleaf uses multiple datasource beans each with a specific purpose.
webDS
- the general datasource that is used to manage the majority of the entities within broadleaf.webStorageDS
- the datasource that is used to store static CMS assetswebEventDS
- the datasource that is used to manage broadleaf scheduled jobs and eventswebSecureDS
- the datasource that is used to store credit card and payment information (this datasource is not used if you are not storing explicit payment information, which is the normal case)
In ReferenceSite these beans are referenced in a map bean called blMergedDataSources
which is created in the CorePersistenceConfig
configuration class
@Autowired
@Qualifier("webDS")
DataSource webDS;
@Autowired
@Qualifier("webSecureDS")
DataSource webSecureDS;
@Autowired
@Qualifier("webStorageDS")
DataSource webStorageDS;
@Autowired
@Qualifier("webEventDS")
DataSource webEventDS;
@Bean
public MapFactoryBean blMergedDataSources() throws Exception {
MapFactoryBean mapFactoryBean = new MapFactoryBean();
Map<String, DataSource> sourceMap = new HashMap<>();
sourceMap.put("jdbc/web", webDS);
sourceMap.put("jdbc/webSecure", webSecureDS);
sourceMap.put("jdbc/cmsStorage", webStorageDS);
sourceMap.put("jdbc/event", webEventDS);
mapFactoryBean.setSourceMap(sourceMap);
return mapFactoryBean;
}
These beans are then referenced by their map keys in the entries in the persistence-core.xml
file, which configure which datasources each persistence unit should use.
<persistence-unit name="blPU" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>jdbc/web</non-jta-data-source>
<exclude-unlisted-classes/>
</persistence-unit>
<persistence-unit name="blSecurePU" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>jdbc/webSecure</non-jta-data-source>
<exclude-unlisted-classes/>
</persistence-unit>
<persistence-unit name="blCMSStorage" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>jdbc/cmsStorage</non-jta-data-source>
<exclude-unlisted-classes/>
</persistence-unit>
<persistence-unit name="blEventPU" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>jdbc/event</non-jta-data-source>
<exclude-unlisted-classes/>
</persistence-unit>
Using Multiple Databases
Sometimes it is beneficial to use different databases to manage the different partitions of data within broadleaf. For instance it might be beneficial to store CMS assets in a separate database that is better optimized for that type of data. Since broadleaf already uses separate datasources to manage different data, it is easy to setup multiple separate database connections.
The different datasource beans listed above are usually defined automatically for you within the broadleaf-boot-starter-database dependency. However, the definitions are annotated with @ConditionalOnMissingBean
, which means that if you define one of the beans manually within your project, it will take precedence. Assuming you have already setup your project to use a database (MS SQL Server, MySQL, Oracle DB, PostgreSQL), all that you have to do to use a different database for a specific datasource is just redefine the datasource bean within you project. Here is an example of using 2 different mysql databases for the webEventDS and the webStorageDS:
@Bean
public DataSource webEventDS() {
return DataSourceBuilder
.create()
.username("webUser")
.password("password")
.url("jdbc:mysql://localhost:3306/event")
.driverClassName("com.mysql.jdbc.Driver")
.type(JDBCDataSource.class)
.build();
}
@Bean
public DataSource webStorageDS() {
return DataSourceBuilder
.create()
.username("contentUser")
.password("password")
.url("jdbc:mysql://localhost:3306/cms")
.driverClassName("com.mysql.jdbc.Driver")
.type(JDBCDataSource.class)
.build();
}
Using different types of databases
You can also have different data sources pointing to completely different database platforms. One use case for this is to use a shared database in local development between developers. If you are using the Broadleaf jobs and events and pointing the webEventDS
to the shared database then you can run into issues with admin deployments and running scheduled jobs since local developer 'nodes' will continually drop in and out. Instead, you can keep all of the jobs and events data within a local HSQLDB. Here is an example, which also assumes that you are using the broadleaf-boot-starter-hsql-database
:
@Bean
public DataSource webEventDS() {
DataSource dataSource = DataSourceBuilder
.create()
.username("SA")
.password("")
.url("jdbc:hsqldb:hsql://localhost/broadleaf")
.driverClassName("org.hsqldb.jdbcDriver")
.type(org.apache.tomcat.jdbc.pool.DataSource.class)
.build();
((org.apache.tomcat.jdbc.pool.DataSource) dataSource).setInitSQL("SET DATABASE TRANSACTION CONTROL MVCC");
}
You will need to take special care to ensure that the dialect for just the blEventPU
is still set to the HSQLDialect
, and make this datasource always create
the schema on startup:
blEventPU.hibernate.dialect=org.broadleafcommerce.common.dialect.DemoHSQLDialect
blEventPU.hibernate.hbm2ddl.auto=create