Spring JPA – Multiple Databases
来源:互联网 发布:淘宝国新西兰能用吗 编辑:程序博客网 时间:2024/06/03 20:11
1. Overview
In this tutorial we’ll implement a simple Spring configuration for a Spring Data JPA system withmultiple databases.
2. The Entities
First – let’s create two simple entities – each living in a separate database.
Here is the first entity “User“:
package
org.baeldung.persistence.multiple.model.user;
@Entity
@Table
(schema =
"spring_jpa_user"
)
public
class
User {
@Id
@GeneratedValue
(strategy = GenerationType.AUTO)
private
int
id;
private
String name;
@Column
(unique =
true
, nullable =
false
)
private
String email;
private
int
age;
}
And the second entity – “Product“:
package
org.baeldung.persistence.multiple.model.product;
@Entity
@Table
(schema =
"spring_jpa_product"
)
public
class
Product {
@Id
private
int
id;
private
String name;
private
double
price;
}
As you can see, the two entities are also placed in independent packages – this will be important as we move into the configuration.
3. The JPA Repositories
Next – let’s take a look at our two JPA repositories – UserRepository:
package
org.baeldung.persistence.multiple.dao.user;
public
interface
UserRepository
extends
JpaRepository<User, Integer> { }
And ProductRepository:
package
org.baeldung.persistence.multiple.dao.product;
public
interface
ProductRepository
extends
JpaRepository<Product, Integer> { }
Note, again how we created these two repositories in different packages.
4. Configure JPA with Java
Next – let’s get to the actual Spring configuration. We’ll start by setting up 2 configuration classes – one for theUser and the other for the Product.
In each one of this configuration classes, we’ll need to define the following:
- User DataSource
- User EntityManagerFactory (userEntityManager)
- User TransactionManager (userTransactionManager)
Let’s start by looking the the User configuration:
@Configuration
@PropertySource
({
"classpath:persistence-multiple-db.properties"
})
@EnableJpaRepositories
(
basePackages =
"org.baeldung.persistence.multiple.dao.user"
,
entityManagerFactoryRef =
"userEntityManager"
,
transactionManagerRef =
"userTransactionManager"
)
public
class
UserConfig {
@Autowired
private
Environment env;
@Bean
@Primary
public
LocalContainerEntityManagerFactoryBean userEntityManager() {
LocalContainerEntityManagerFactoryBean em =
new
LocalContainerEntityManagerFactoryBean();
em.setDataSource(userDataSource());
em.setPackagesToScan(
new
String[] {
"org.baeldung.persistence.multiple.model.user"
});
HibernateJpaVendorAdapter vendorAdapter =
new
HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties =
new
HashMap<String, Object>();
properties.put(
"hibernate.hbm2ddl.auto"
, env.getProperty(
"hibernate.hbm2ddl.auto"
));
properties.put(
"hibernate.dialect"
, env.getProperty(
"hibernate.dialect"
));
em.setJpaPropertyMap(properties);
return
em;
}
@Primary
@Bean
public
DataSource userDataSource() {
DriverManagerDataSource dataSource =
new
DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty(
"jdbc.driverClassName"
));
dataSource.setUrl(env.getProperty(
"user.jdbc.url"
));
dataSource.setUsername(env.getProperty(
"jdbc.user"
));
dataSource.setPassword(env.getProperty(
"jdbc.pass"
));
return
dataSource;
}
@Primary
@Bean
public
PlatformTransactionManager userTransactionManager() {
JpaTransactionManager transactionManager =
new
JpaTransactionManager();
transactionManager.setEntityManagerFactory(userEntityManager().getObject());
return
transactionManager;
}
}
Notice how we’re using the userTransactionManager as our PrimaryTransactionManager – 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 ProductConfig – where we define similar beans:
@Configuration
@PropertySource
({
"classpath:persistence-multiple-db.properties"
})
@EnableJpaRepositories
(
basePackages =
"org.baeldung.persistence.multiple.dao.product"
,
entityManagerFactoryRef =
"productEntityManager"
,
transactionManagerRef =
"productTransactionManager"
)
public
class
ProductConfig {
@Autowired
private
Environment env;
@Bean
public
LocalContainerEntityManagerFactoryBean productEntityManager() {
LocalContainerEntityManagerFactoryBean em =
new
LocalContainerEntityManagerFactoryBean();
em.setDataSource(productDataSource());
em.setPackagesToScan(
new
String[] {
"org.baeldung.persistence.multiple.model.product"
});
HibernateJpaVendorAdapter vendorAdapter =
new
HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties =
new
HashMap<String, Object>();
properties.put(
"hibernate.hbm2ddl.auto"
, env.getProperty(
"hibernate.hbm2ddl.auto"
));
properties.put(
"hibernate.dialect"
, env.getProperty(
"hibernate.dialect"
));
em.setJpaPropertyMap(properties);
return
em;
}
@Bean
public
DataSource productDataSource() {
DriverManagerDataSource dataSource =
new
DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty(
"jdbc.driverClassName"
));
dataSource.setUrl(env.getProperty(
"product.jdbc.url"
));
dataSource.setUsername(env.getProperty(
"jdbc.user"
));
dataSource.setPassword(env.getProperty(
"jdbc.pass"
));
return
dataSource;
}
@Bean
public
PlatformTransactionManager productTransactionManager() {
JpaTransactionManager transactionManager =
new
JpaTransactionManager();
transactionManager.setEntityManagerFactory(productEntityManager().getObject());
return
transactionManager;
}
}
5. Simple Test
Finally – let’s test our configurations.
We will try a simple test by creating an instance of each entity and make sure it is created – as in the following example:
@RunWith
(SpringJUnit4ClassRunner.
class
)
@ContextConfiguration
(classes = { UserConfig.
class
, ProductConfig.
class
})
@TransactionConfiguration
public
class
JPAMultipleDBTest {
@Autowired
private
UserRepository userRepository;
@Autowired
private
ProductRepository productRepository;
@Test
@Transactional
(
"userTransactionManager"
)
public
void
whenCreatingUser_thenCreated() {
User user =
new
User();
user.setName(
"John"
);
user.setEmail(
"john@test.com"
);
user.setAge(
20
);
user = userRepository.save(user);
assertNotNull(userRepository.findOne(user.getId()));
}
@Test
@Transactional
(
"userTransactionManager"
)
public
void
whenCreatingUsersWithSameEmail_thenRollback() {
User user1 =
new
User();
user1.setName(
"John"
);
user1.setEmail(
"john@test.com"
);
user1.setAge(
20
);
user1 = userRepository.save(user1);
assertNotNull(userRepository.findOne(user1.getId()));
User user2 =
new
User();
user2.setName(
"Tom"
);
user2.setEmail(
"john@test.com"
);
user2.setAge(
10
);
try
{
user2 = userRepository.save(user2);
}
catch
(DataIntegrityViolationException e) {
}
assertNull(userRepository.findOne(user2.getId()));
}
@Test
@Transactional
(
"productTransactionManager"
)
public
void
whenCreatingProduct_thenCreated() {
Product product =
new
Product();
product.setName(
"Book"
);
product.setId(
2
);
product.setPrice(
20
);
product = productRepository.save(product);
assertNotNull(productRepository.findOne(product.getId()));
}
}
6. Conclusion
This article was a practical overview of how to configure your Spring Data JPA project to use multiple databases.
The full implementation of this article can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.
- Spring JPA – Multiple Databases
- Distributed transactions with multiple databases, Spring Boot, Spring Data JPA and Atomikos
- Distributed transactions with multiple databases, Spring Boot, Spring Data JPA and Atomikos
- Spring Data repositories with multiple databases
- Mybatis Spring multiple databases Java configuration
- configure Spring+Hibernate+JPA for work with two databases
- django dynamic multiple databases
- Using NHibernate with Multiple Databases
- Opening multiple databases with SQLite
- Access multiple databases through PhpMyadmin
- How to setup multiple data sources with Spring and JPA
- How to setup multiple data sources with Spring and JPA
- spring + jpa
- spring+jpa
- Spring JPA
- spring jpa
- spring+jpa
- JPA+Spring
- Volley NetworkDispatcher
- PYTHONDAY1
- 每天一个linux命令(5):rm 命令
- 使用fn_dblog解析SQL SERVER 数据库日志方法
- php扩展开发(二 一个程序的生命周期)
- Spring JPA – Multiple Databases
- 部署图(Deployment Diagram)—UML图(九)
- perl学习笔记---debug
- MarkDown编辑器基本用法
- 禁止直接在Webservice.asmx页面调用的方法
- android 广播
- html代码转化成pdf文件
- 构件图(Component Diagram)—UML图(八)
- [李景山php]每天TP5-20161230|thinkphp5-Cookie.php