Ich versuche, zwei EntityManagerFactory
für eine Spring-Boot-Anwendung zu konfigurieren. Jeder dieser EntityManagerFactory
s sollte mit verschiedenen Datenbanken arbeiten. Es wäre auch toll, wenn einer von ihnen als Standard verwendet würde (z. B. wenn nicht explizit angegeben wurde, welche Information verwendet werden sollte).Mit zwei EntityManagerFactory innerhalb einer Spring-Boot-App
Hier ist mein Code:
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/Repositories/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);
}
}
pkg/Repositories/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'
}
}
Ausführen dieses app, die ich nächste Störung erhalte:
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