Multiple datasource configuration
06/07/24 9:12 AM
1. The Entities
First, let’s create two simple entities, with each living in a separate database.
Here is the first User entity:
package [Link];
@Entity
@Table(schema = "users")
public class User {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String name;
@Column(unique = true, nullable = false)
private String email;
private int age;
}
And here’s the second entity, Product:
package [Link];
@Entity
@Table(schema = "products")
public class Product {
@Id
private int id;
private String name;
private double price;
}
We can see that the two entities are also placed in independent packages. This will be important as we move into the
configuration.
2. The JPA Repositories
Next, let’s take a look at our two JPA repositories, UserRepository:
package [Link];
public interface UserRepository
extends JpaRepository<User, Integer> { }
and ProductRepository:
package [Link];
public interface ProductRepository
extends JpaRepository<Product, Integer> { }
Note again how we created these two repositories in different packages.
3. Configure JPA With Java
Now we’ll get to the actual Spring configuration. We’ll first set up two configuration classes — one for the User and the other for
the Product.
In each configuration class, we’ll need to define the following interfaces for User:
○ DataSource
○ EntityManagerFactory (userEntityManager)
○ TransactionManager (userTransactionManager)
Let’s start by looking at the User configuration:
@Configuration
@PropertySource({ "classpath:[Link]" })
@EnableJpaRepositories(
basePackages = "[Link]",
entityManagerFactoryRef = "userEntityManager",
transactionManagerRef = "userTransactionManager"
)
public class PersistenceUserConfiguration {
@Autowired
private Environment env;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean userEntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
[Link](userDataSource());
[Link](
new String[] { "[Link]" });
HibernateJpaVendorAdapter vendorAdapter
= new HibernateJpaVendorAdapter();
[Link](vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
[Link]("[Link]",
[Link]("[Link]"));
[Link]("[Link]",
[Link]("[Link]"));
[Link](properties);
return em;
}
@Primary
@Bean
public DataSource userDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
[Link](
[Link]("[Link]"));
[Link]([Link]("[Link]"));
[Link]([Link]("[Link]"));
[Link]([Link]("[Link]"));
return dataSource;
}
@Primary
@Bean
public PlatformTransactionManager userTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
[Link](
userEntityManager().getObject());
return transactionManager;
}
}
Notice how we use the userTransactionManager as our Primary TransactionManager by annotating the bean definition
with @Primary. That’s helpful whenever we’re going to implicitly or explicitly inject the transaction manager without specifying which
one by name.
Next, let’s discuss PersistenceProductConfiguration, where we define similar beans:
@Configuration
@PropertySource({ "classpath:[Link]" })
@EnableJpaRepositories(
basePackages = "[Link]",
entityManagerFactoryRef = "productEntityManager",
transactionManagerRef = "productTransactionManager"
)
public class PersistenceProductConfiguration {
@Autowired
private Environment env;
@Bean
public LocalContainerEntityManagerFactoryBean productEntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
[Link](productDataSource());
[Link](
new String[] { "[Link]" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
[Link](vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
[Link]("[Link]",
[Link]("[Link]"));
[Link]("[Link]",
[Link]("[Link]"));
[Link](properties);
return em;
}
@Bean
public DataSource productDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
[Link](
[Link]("[Link]"));
[Link]([Link]("[Link]"));
[Link]([Link]("[Link]"));
[Link]([Link]("[Link]"));
return dataSource;
}
@Bean
public PlatformTransactionManager productTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
[Link](
productEntityManager().getObject());
return transactionManager;
}
}