在一个弹簧启动应用程序中使用两个EntityManagerFactory
问题描述:
我试图为一个弹簧启动应用程序配置两个EntityManagerFactory
。这些EntityManagerFactory
中的每一个都应该与不同的数据库一起工作。如果将其中一个用作默认值(例如,在没有提供明确的信息时应该使用哪一个),这也会很好。在一个弹簧启动应用程序中使用两个EntityManagerFactory
这里是我的代码:
PKG/Application.java
package pkg;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).run(args);
}
}
PKG/PrimaryDbConfig.java
package pkg;
import org.h2.jdbcx.JdbcDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
@Configuration
public class PrimaryDbConfig {
public static final String DB = "primary";
@Bean
@Primary
public DataSource primaryDataSource() {
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:file:~\\db\\test;AUTO_SERVER=TRUE");
ds.setUser("sa");
ds.setPassword("sa");
return ds;
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName(DB);
factoryBean.setDataSource(primaryDataSource());
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factoryBean.setPackagesToScan("pkg.entities");
return factoryBean;
}
@Bean
@Primary
public PlatformTransactionManager primaryTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(primaryEntityManagerFactoryBean().getObject());
return transactionManager;
}
}
PKG/SecondaryDbConfig.java
package pkg;
import org.h2.jdbcx.JdbcDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
@Configuration
public class SecondaryDbConfig {
public static final String DB = "secondary";
@Bean
public DataSource secondaryDataSource() {
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:file:~\\db\\test2;AUTO_SERVER=TRUE");
ds.setUser("sa");
ds.setPassword("sa");
return ds;
}
@Bean
public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName(DB);
factoryBean.setDataSource(secondaryDataSource());
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factoryBean.setPackagesToScan("pkg.entities");
return factoryBean;
}
@Bean
public PlatformTransactionManager secondaryTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(secondaryEntityManagerFactoryBean().getObject());
return transactionManager;
}
}
PKG /库/ P rimaryRepository.java
package pkg.repositories;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import pkg.entities.SomeEntity;
import javax.persistence.EntityManager;
@Repository
@Transactional
public class PrimaryRepository {
private final EntityManager entityManager;
public PrimaryRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
public SomeEntity find(Integer id) {
return entityManager.find(SomeEntity.class, id);
}
}
包装/库/ SecondaryRepository.java
package pkg.repositories;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import pkg.entities.SomeEntity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Repository
@Transactional("secondaryTransactionManager")
public class SecondaryRepository {
@PersistenceContext(unitName = "secondary")
private final EntityManager entityManager;
public SecondaryRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
public SomeEntity find(Integer id) {
return entityManager.find(SomeEntity.class, id);
}
}
的build.gradle
plugins {
id 'org.springframework.boot' version '1.5.7.RELEASE'
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile "com.h2database:h2:1.4.193"
compile "org.hibernate:hibernate-core:5.2.10.Final"
compile ("org.springframework.boot:spring-boot-starter-data-jpa:1.5.2.RELEASE") {
exclude module: 'tomcat-jdbc'
}
}
运行这个程序,我得到一个错误:
Description:
Parameter 0 of constructor in pkg.repositories.PrimaryRepository required a single bean, but 2 were found:
- org.springframework.orm.jpa.SharedEntityManagerCreator#0: defined by method 'createSharedEntityManager' in null
- org.springframework.orm.jpa.SharedEntityManagerCreator#1: defined by method 'createSharedEntityManager' in null
答
You have to add this in your dbconfiguration (in both classes) :
@Configuration
@PropertySource({ "classpath:persistence-cities-db.properties" })
@EnableJpaRepositories(
basePackages = "com.viajaneando.persistence.cities.dao.city",
entityManagerFactoryRef = "cityEntityManager",
transactionManagerRef = "cityTransactionManager"
)
无论如何,我不明白你的问题是什么