Spring Data repositories with multiple databases
来源:互联网 发布:怎样做一个软件 编辑:程序博客网 时间:2024/05/22 06:42
有人遇到了这样的需求,参考了这样一篇博客的文章。转自:http://scattercode.co.uk/2013/11/18/spring-data-multiple-databases/
参考代码地址:https://github.com/gratiartis/multids-demo
The Spring Data project keeps making it easier to do database access in Spring applications, and one of the neatest improvements of recent times is that by defining an interface which extends JpaRepository and referencing a JPA entity, an implementation will automatically be injected with all the usual CRUD methods: findAll(), findOne(id), save(entity), delete(id), etc.
Recently I was working on a project, where I had taken full advantage of this, and for which I needed to add domain objects from an additional database. Unfortunately, as soon as I added references to entities in a different database I started experiencing troubles. For instance:
Not an managed type: class com.sctrcd.multidsdemo.domain.bar.Bar
… which was being caused by my repository being injected with the entityManager and transactionManager for the other database. After naming my beans to ensure that I would not be referencing the wrong one, I started seeing:
No bean named 'entityManagerFactory' is defined.
… because the repository implementation defaults to a by-name search for a bean called “entityManagerFactory”.
I was struggling to find any documentation of how to do it right, so to help me work through the steps of such a configuration, I created a minimal demo project at GitHub, containing two entities with those traditional names: Foo and Bar.
https://github.com/gratiartis/multids-demo
Here I shall explain the configuration that I ended up with in the hope that readers might understand that it can be done, and that it’s actually quite easy and requires very little code, if you know how!
First of all, we set up two JPA entities, Foo and Bar:
@Entity public class Foo { /* Constructors, fields and accessors/mutators */ }@Entity public class Bar { /* Constructors, fields and accessors/mutators */ }
Associated with these we create two repositories: FooRepository and BarRepository. Thanks to the awesomeness of Spring Data, we can get ourselves some pretty full-featured repositories purely by defining interfaces which extend JpaRepository:
public interface FooRepository extends JpaRepository<Foo, Long> {}public interface BarRepository extends JpaRepository<Bar, Long> {}
We need to ensure that each of these maps to a table in its own database. To achieve this, we will need two separate entity managers, each of which has a different datasource. However, in a Spring Java config @Configuration class, we can only have one @EnableJpaRepositories annotation and each such annotation can only reference one EntityManagerFactory. To achieve this, we create two separate @Configuration classes:FooConfig and BarConfig.
Each of these @Configuration classes defines a DataSource based on an embedded HSQL database. The following is the BarConfig. FooConfig is identical except for some different names and package paths.
@Configuration@EnableTransactionManagement@EnableJpaRepositories(entityManagerFactoryRef = "barEntityManagerFactory",transactionManagerRef = "barTransactionManager",basePackages = { "com.sctrcd.multidsdemo.integration.repositories.bar" })public class BarConfig {@AutowiredJpaVendorAdapter jpaVendorAdapter;/*** Primary because if we have activated embedded databases, we do not want* the application to connect to an external database.*/@Bean(name = "barDataSource")public DataSource dataSource() {return new EmbeddedDatabaseBuilder().setName("bardb").setType(EmbeddedDatabaseType.HSQL).build();}@Bean(name = "barEntityManager")public EntityManager entityManager() {return entityManagerFactory().createEntityManager();}@Bean(name = "barEntityManagerFactory")public EntityManagerFactory entityManagerFactory() {LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();lef.setDataSource(dataSource());lef.setJpaVendorAdapter(jpaVendorAdapter);lef.setPackagesToScan("com.sctrcd.multidsdemo.domain.bar");lef.setPersistenceUnitName("barPersistenceUnit");lef.afterPropertiesSet();return lef.getObject();}@Bean(name = "barTransactionManager")public PlatformTransactionManager transactionManager() {return new JpaTransactionManager(entityManagerFactory());}}
Each configuration should define a DataSource, EntityManager, EntityManagerFactory and PlatformTransactionManager. You need to make sure that @Entity beans for different data sources are in different packages. We then need to put the correct references in the @EnableJpaRepositories annotation for each @Configuration class.
@Configuration@EnableTransactionManagement@EnableJpaRepositories( entityManagerFactoryRef = "barEntityManagerFactory", transactionManagerRef = "barTransactionManager", basePackages = {"com.sctrcd.multidsdemo.integration.repositories.bar"})public class BarConfig { // ...}@Configuration@EnableTransactionManagement@EnableJpaRepositories( entityManagerFactoryRef = "barEntityManagerFactory", transactionManagerRef = "barTransactionManager", basePackages = { "com.sctrcd.multidsdemo.integration.repositories.bar" })public class BarConfig { // ...}
As you can see, each of these @EnableJpaRepositories annotations defines a specific named EntityManagerFactory and PlatformTransactionManager. They also specify which repositories should be wired up with those beans. In the example, I have put the repositories in database-specific packages. It is also possible to define each individual repository by name, by adding includeFilters to the annotation, but by segregating the repositories by database, I believe that things should end up more readable.
At this point you should have a working application using Spring Data repositories to manage entities in two separate databases. Feel free to grab the project from the link above and run the tests to see this happening. And please do let me know if you can spot any good opportunities for improvement.
- Spring Data repositories with 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
- Using NHibernate with Multiple Databases
- Opening multiple databases with SQLite
- Spring JPA – Multiple Databases
- Spring Data Repositories 使用记录
- Spring Data Redis(Redis Repositories)
- Spring Data Redis(Repositories-Keyspaces)
- Mybatis Spring multiple databases Java configuration
- How to setup multiple data sources with Spring and JPA
- How to setup multiple data sources with Spring and JPA
- Spring Data JPA repositories using JavaConfig
- Spring Data Redis(Repositories-Secondary Indexes)
- Spring Data Redis(Repositories-Time To Live)
- Spring Data Redis(Repositories-Persisting References)
- Spring Data Redis(Repositories-CDI integration)
- Redis学习笔记II-Working with Multiple Databases
- 追逐自己的梦想----------辅助制作第四课:将游戏人物数据进行测试
- ajaxfileupload IE兼容问题
- vim 基本配置文件.vimrc 简介
- Android蛋疼错误各种尝试
- 字节
- Spring Data repositories with multiple databases
- 第三十三篇:Win8.1中USB xHCI驱动的符号列表
- fd_set 用法
- 属性,实例变量和成员变量
- 文字飞入和飞出
- 创建自己的oracle解释计划
- android NDK开发编译C++文件出现Type 'jint' could not be resolved和Unresolved inclusion: <jni...
- hibernate-数据库-创建表-DBBrowser中连接配置
- hdu 1007 Quoit Design(平面分治)