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