Mehreren repositories eigene EntityManager zuweisen

Harald123

Mitglied
Hallo zusammen,

ich versuche in Spring zwei repositories zu verwenden mit eingenem entityManager, da sie auf unterschiedliche Datenbanken zugreifen.
Dies sollte mit der @EnableJpaRepositories Anmerkung funktionieren, was aber beim Ausführen passiert ist dass entityManagerFactory-repo2 für beide
verwendet wird, da dieses Bean beim Aufbauen des Spring Context als letztes erstellt wird. Somit wird die "entityManagerFactoryRef" Eigenschaft
der @EnableJpaRepositories Anmerkung ignoriert. Sonst funktioneren die repositories gut.

Gibt es also noch etwas zu beachten um einem Repository eine bestimmte Datenquelle/EntityManagerFactory / EntityManager zuzuweisen, ohne dass nur das
zuletzt erstelle verwendet wird?


Hier sind die Konfiguration Klassen:



Java:
@Configuration
@PropertySource(value = { "classpath:hibernate.properties" })
@EnableJpaRepositories(basePackageClasses = <paket>.repo1.class,
        entityManagerFactoryRef = "entityManagerFactory-repo1")
public class KonfigurationRepo1
{

    @Autowired
    private Environment         env;



    @Bean(name = "entityManagerFactory-repo1")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanrepo1()
    {
        ...
       
        return entityManagerFactoryBean;
    }


    @Bean(name = "datasource-repo1")
    public DataSource dataSource()
    {
        ...

        return dataSource;
    }
   
}


und noch einmal eine äquivalente Klasse zu repo2
 

Oneixee5

Top Contributor
Ich mache das (in einer ältern Anwendung) so wie unten und das funktioniert (basePackages - habe ich für den Post verändert):
Java:
@Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean pgsqlEntityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("pgsqlDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages(PACKAGES_TO_SCAN)
                .build();

    }

    @Bean
    public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("mysqlDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages(PACKAGES_TO_SCAN)
                .build();

    }
Java:
    @Bean
    @Primary
    public PlatformTransactionManager pgsqlTransactionManager(@Qualifier("pgsqlEntityManagerFactory") EntityManagerFactory pgsqlEntityManagerFactory) {
        return new JpaTransactionManager(pgsqlEntityManagerFactory);
    }

    @Bean
    public PlatformTransactionManager mysqlTransactionManager(@Qualifier("mysqlEntityManagerFactory") EntityManagerFactory mysqlEntityManagerFactory) {
        return new JpaTransactionManager(mysqlEntityManagerFactory);
    }
Java:
@EnableJpaRepositories(
        entityManagerFactoryRef = "pgsqlEntityManagerFactory",
        transactionManagerRef = "pgsqlTransactionManager",
        basePackages = "de.package.mysql.repositories"
)

@EnableJpaRepositories(
        entityManagerFactoryRef = "mysqlEntityManagerFactory",
        transactionManagerRef = "mysqlTransactionManager",
        basePackages = "de.package.postgres.repositories"
)
 

Harald123

Mitglied
Danke für den Vorschlag.
Ich habe es wie unten versucht, aber es wird weiter die Verbindung / entityManagerFactory von repo2 verwendet statt repo1. Dabei habe ich mit autowired, mit Primary und mit beiden versucht. Zusätzlich noch mit der Methode die "entityManagerFactory-repo1" erstellt statt dem übergebenen "entityManagerFactory" Parameter.



Java:
@EnableJpaRepositories(basePackageClasses = <paket>.Repo1.class,
        entityManagerFactoryRef = "entityManagerFactory-repo1", transactionManagerRef = "transactionManagerRepo1")
public class KonfigurationRepo1

Bean(name = "transactionManagerRepo1")
    // @Autowired
    @Primary
    PlatformTransactionManager transactionManagerRepo1(
            @Qualifier("entityManagerFactory-repo1") final EntityManagerFactory entityManagerFactory)
    {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        
        return transactionManager;
    }
 

Oneixee5

Top Contributor
public class KonfigurationRepo1 braucht @Configuration

basePackageClasses: Type-safe alternative to basePackages() for specifying the packages to scan for annotated components. The package of each class specified will be scanned. Consider creating a special no-op marker class or interface in each package that serves no purpose other than being referenced by this attribute.
Du solltest also in basePackageClasses keine Repository-Klasse angeben und die jeweiligen Repositories müssen in verschiedenen Packages liegen.
 

Harald123

Mitglied
ja, die Konfiguration Klasse hat @Configuration

ich habe es so eingebaut wie Sie hingewiesen haben und es hat funktioniert. Vielen Dank! Hat mir viel Aufwand erspart!
 

Neue Themen


Oben