Two Spring JPA Datasources for Development and Testing Equals Four

We've had separate datasources in our NixMash Spring project for a long time now, a MySQL Datasource for development and an H2 Datasource for Tests. I blogged a bit about that configuration in this NixMash post and you can find the source on GitHub.

What we're talking about today is not just two datasources which conform to two separate Spring Profiles (“mysql” and “h2” in our case), but two datasources for development and two different datasources for testing. Four datasources, four Entity Managers, four Transaction Managers.

It will help if I quickly describe the new project for which this Spring JPA configuration was designed. We're building a new app (perhaps complete by the time you read this) which migrates WordPress Blog data to NixMash Spring. It's on GitHub here, the WP to NixMash Spring Migrator. Our four datasources then, are:

For Development

  1. The WordPress MySQL Database from where we're exporting the data
  2. The NixMash Spring MySQL Database destination

For Testing

  1. A WordPress MySQL Database to retrieve the test data
  2. An H2 Database we'll create and drop on each Test Launch

Our JpaConfig is where the action is, of course. We have a separate JpaTestConfig class in our test classes. You'll see that the JpaConfig class has a @Profile(“mysql”) annotation, so it's as easy as that to determine the JPA Configuration file at runtime. The folded JpaConfig class below lists the areas we'll touch on in this post: Datasources, EntityManagerFactories, PlatformTransactionManagers, and two static JpaRepository Configuration classes.

Persistence Units

Persistence Units play an important part when using multiple datasources, entity and transaction managers. They are defined here, where you see we're using WP for the WordPress MySQL database and LOCAL for the destination database.

Data Sources

Even with multiple datasources, leveraging Spring's DataSourceBuilder and supported property names in application.properties requires little code. It's important to note the @Primary designation on the default datasource, which is our LOCAL MySQL destination database.

I mentioned the supported property names in application.properties. Here are the above properties with @ConfigurationProperties in play.

Entity Manager Factories

Our Entity Managers are defined next. We're using the @Primary designation again, defining the Persistence Unit and Datasource for each, and are separating the two by package location.

Transaction Managers

We're going to setup a standard JpaTransactionManager Bean for our @Primary Transaction Manager, but you'll notice we use the PlatformTransactionManager Interface for our secondary WP Transaction Manager.

JPA Repository Configuration Classes

We're adding two inner static Configuration Classes to the mix where we designate the Entity and Transaction Managers and Base Packages for the Repositories. You'll notice we don't have to include the entityManagerFactoryRef and transactionManagerRefs to our default Repository since they will use the default object names of “entityManagerFactory” and “transactionManager.” IntelliJ is Spring-savvy enough to point that out to you, which is one pretty darn smart IDE.

Usage Notes

Separation of the Persistence Unit objects is a good idea. That separation is shown in the application package structure below. “migrator.db.local.*” and “migrator.db.wp.*”.

Using the Persistence Unit Name is shown below on a WP Service class. With the class marked with @Transactional you can apply Transactions to the methods or to an EntityManager as you see here.

Those are the main points of a dual-environment, multi-datasource configuration. Grab the source on GitHub for the details.

Posted January 20, 2017 10:10 AM EST

More Like This Post