You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无persistence.xml的Spring MVC 4多EntityManagerFactory配置问询

Configuring Multiple EntityManagerFactory Beans in Spring MVC 4 (Java-Based JPA Setup)

Got it, let's walk through exactly how to set up multiple EntityManagerFactory beans in your Spring MVC 4 project—since you're using Java config instead of persistence.xml, this is totally doable with a few key tweaks.

Step 1: Define Separate Data Sources

First, you'll need a dedicated DataSource bean for each database you want to connect to. These will power their corresponding EntityManagerFactory instances.

package test.conf;

import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    // Primary data source (marked as default when no qualifier is specified)
    @Primary
    @Bean(name = "primaryDataSource")
    public DataSource primaryDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/primary_db");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        return dataSource;
    }

    // Secondary data source for your second database
    @Bean(name = "secondaryDataSource")
    public DataSource secondaryDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/secondary_db");
        dataSource.setUsername("postgres");
        dataSource.setPassword("postgres");
        return dataSource;
    }
}

Step 2: Create Corresponding EntityManagerFactory Beans

Next, build an EntityManagerFactory for each data source. Make sure to:

  • Use unique bean names
  • Link the correct DataSource with @Qualifier
  • Scan only entity classes specific to each database (avoids cross-database entity conflicts)
  • Set JPA properties tailored to each database's dialect and behavior
package test.conf;

import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.beans.factory.annotation.Qualifier;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
public class JpaConfig {

    // Primary EntityManagerFactory (default)
    @Primary
    @Bean(name = "primaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
            @Qualifier("primaryDataSource") DataSource dataSource) {
        
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("test.entity.primary"); // Entities belonging to primary DB
        
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        
        Properties jpaProperties = new Properties();
        jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
        jpaProperties.setProperty("hibernate.hbm2ddl.auto", "update");
        em.setJpaProperties(jpaProperties);
        
        return em;
    }

    // Secondary EntityManagerFactory
    @Bean(name = "secondaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("test.entity.secondary"); // Entities belonging to secondary DB
        
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        
        Properties jpaProperties = new Properties();
        jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        jpaProperties.setProperty("hibernate.hbm2ddl.auto", "validate");
        em.setJpaProperties(jpaProperties);
        
        return em;
    }
}

Step 3: Add Transaction Managers for Each EntityManagerFactory

Each EntityManagerFactory needs its own PlatformTransactionManager to handle transactions for that database.

package test.conf;

import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManagerFactory;

@Configuration
public class TransactionConfig {

    @Primary
    @Bean(name = "primaryTransactionManager")
    public PlatformTransactionManager primaryTransactionManager(
            @Qualifier("primaryEntityManagerFactory") EntityManagerFactory emf) {
        
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Bean(name = "secondaryTransactionManager")
    public PlatformTransactionManager secondaryTransactionManager(
            @Qualifier("secondaryEntityManagerFactory") EntityManagerFactory emf) {
        
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }
}

Step 4: Use the Correct EntityManager/Transaction Manager in Your Code

When working with a specific database, use @Qualifier or unitName to inject the right EntityManager, and specify the matching transaction manager in @Transactional.

Example DAO for Secondary Database:

package test.dao;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import test.entity.secondary.SecondaryEntity;

@Repository
public class SecondaryDao {

    @PersistenceContext(unitName = "secondaryEntityManagerFactory")
    private EntityManager entityManager;

    @Transactional(value = "secondaryTransactionManager")
    public void saveSecondaryEntity(SecondaryEntity entity) {
        entityManager.persist(entity);
    }
}

For Spring Data JPA Repositories:

Configure separate repository scans with explicit references to the correct EntityManagerFactory and TransactionManager:

@Configuration
@EnableJpaRepositories(
        basePackages = "test.repository.primary",
        entityManagerFactoryRef = "primaryEntityManagerFactory",
        transactionManagerRef = "primaryTransactionManager"
)
@EnableJpaRepositories(
        basePackages = "test.repository.secondary",
        entityManagerFactoryRef = "secondaryEntityManagerFactory",
        transactionManagerRef = "secondaryTransactionManager"
)
public class JpaRepositoryConfig {
    // No extra beans needed here if already defined above
}

Key Reminders:

  • Use distinct bean names and @Qualifier to avoid ambiguity between beans
  • @Primary marks one bean as the default when no qualifier is specified—optional but helpful if most of your code uses one database
  • Keep entity classes for different databases in separate packages to prevent unintended scanning by the wrong EntityManagerFactory

内容的提问来源于stack exchange,提问作者marionmaiden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:55:51