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

如何使用JPA的EntityManager配置多MySQL数据库?

问题描述

尝试使用EntityManager连接两个MySQL数据库,此前用Hibernate成功配置过多库,但通过@PersistenceContext(unitName = "foo")注入EntityManager时失败。

现有XML配置:

<bean name="configds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${driverClassName}" />
        <property name="url" value="${configUrl}" />
        <property name="username" value="${configName}" />
        <property name="password" value="${configPass}" />
    </bean>

    <bean class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" name="configFac">
        <property name="dataSource" ref="configds" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.hbm2ddl.auto">none</prop>
            </props>
        </property>
      
        <property name="packagesToScan">
            <list>
                <value>com.visa.entities</value>
            </list>
        </property>
    </bean>

        <bean name="configTemp" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <property name="sessionFactory" ref="configFac" />
    </bean>

    <bean name="configTxn" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="configFac" />
    </bean>

<!--__________________________________________ DB for visa_slovakia ______________________________________________-->

<bean name="svkds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${driverClassName}" />
        <property name="url" value="${svkUrl}" />
        <property name="username" value="${svkName}" />
        <property name="password" value="${svkPass}" />
    </bean>

    <bean class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" name="svkFac">
        <property name="dataSource" ref="svkds" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.hbm2ddl.auto">none</prop>
            </props>
        </property>
      
        <property name="packagesToScan">
            <list>
                <value>com.visa.entities</value>
            </list>
        </property>
    </bean>

    <bean name="svkTemp" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <property name="sessionFactory" ref="svkFac" />
    </bean>

    <bean name="svkTxn" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="svkFac" />
    </bean>

DAO层注入代码:

@PersistenceContext(unitName = "configTemp")
private EntityManager configTmp;

@PersistenceContext(unitName = "svkTemp")
private EntityManager svkTmp;

报错信息:

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'configTemp' is expected to be of type 'javax.persistence.EntityManagerFactory' but was actually of type 'org.springframework.orm.hibernate5.HibernateTemplate'

解决方案

1. 替换HibernateTemplate为EntityManagerFactory配置

@PersistenceContext的unitName需要指向EntityManagerFactory类型的bean,而非HibernateTemplate。你需要为每个数据库配置LocalContainerEntityManagerFactoryBean,同时更新事务管理器为JPA类型。

修改XML配置:

删除原有HibernateTemplate bean,新增两个EntityManagerFactory及对应事务管理器:

<!-- 第一个数据库的EntityManagerFactory -->
<bean id="configEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="configds"/>
    <property name="packagesToScan" value="com.visa.entities"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.hbm2ddl.auto">none</prop>
        </props>
    </property>
</bean>

<!-- 第二个数据库的EntityManagerFactory -->
<bean id="svkEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="svkds"/>
    <property name="packagesToScan" value="com.visa.entities"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.hbm2ddl.auto">none</prop>
        </props>
    </property>
</bean>

<!-- 第一个数据库的事务管理器 -->
<bean id="configTxn" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="configEntityManagerFactory"/>
</bean>

<!-- 第二个数据库的事务管理器 -->
<bean id="svkTxn" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="svkEntityManagerFactory"/>
</bean>

注意:原配置重复设置hibernate.dialect,保留一个适配你MySQL版本的即可,建议用MySQL8Dialect。

2. 修正DAO层注入

将@PersistenceContext的unitName指向新配置的EntityManagerFactory的bean id:

@PersistenceContext(unitName = "configEntityManagerFactory")
private EntityManager configTmp;

@PersistenceContext(unitName = "svkEntityManagerFactory")
private EntityManager svkTmp;

3. 可选:保留原有SessionFactory的方案

如果不想完全替换为JPA配置,可通过现有SessionFactory包装出EntityManagerFactory,新增如下bean:

<bean id="configEntityManagerFactory" factory-bean="configFac" factory-method="getObject"/>
<bean id="svkEntityManagerFactory" factory-bean="svkFac" factory-method="getObject"/>

之后同样更新事务管理器和DAO注入即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:49:56