当前位置: 首页 > 面试题库 >

使用Spring时如何注入多个JPA EntityManager(持久性单元)

杜浩壤
2023-03-14
问题内容

我需要使用一个数据库进行查询(非修改),而使用一个数据库进行命令(修改)。我正在使用Spring Data JPA,所以我有两个配置类:

@Configuration
@EnableJpaRepositories(value = "com.company.read",
        entityManagerFactoryRef = "readingEntityManagerFactory",
        transactionManagerRef = "readingTransactionManager")
@EnableTransactionManagement
public class SpringDataJpaReadingConfiguration {

    @Bean(name = "readingEntityManagerFactory")
    public EntityManagerFactory readingEntityManagerFactory() {
        return Persistence.createEntityManagerFactory("persistence.reading");
    }

    @Bean(name = "readingExceptionTranslator")
    public HibernateExceptionTranslator readingHibernateExceptionTranslator() {
        return new HibernateExceptionTranslator();
    }

    @Bean(name = "readingTransactionManager")
    public JpaTransactionManager readingTransactionManager() {
        return new JpaTransactionManager();
    }

}

@Configuration
@EnableJpaRepositories(value = "com.company.write",
        entityManagerFactoryRef = "writingEntityManagerFactory",
        transactionManagerRef = "writingTransactionManager")
@EnableTransactionManagement
public class SpringDataJpaWritingConfiguration {

    @Bean(name = "writingEntityManagerFactory")
    public EntityManagerFactory writingEntityManagerFactory() {
        return Persistence.createEntityManagerFactory("persistence.writing");
    }

    @Bean(name = "writingExceptionTranslator")
    public HibernateExceptionTranslator writingHibernateExceptionTranslator() {
        return new HibernateExceptionTranslator();
    }

    @Bean(name = "writingTransactionManager")
    public JpaTransactionManager writingTransactionManager() {
        return new JpaTransactionManager();
    }

}

在我的存储库中,有时我需要决定与EntityManager一起使用,如下所示:

@Repository
public class UserReadingRepository {

    @PersistenceContext(unitName = "persistence.reading")
    private EntityManager em;

    // some useful queries here
}

我使用在我的定义持久性单元的名称 的persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">

    <persistence-unit name="persistence.reading" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <non-jta-data-source>ReadingDS</non-jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>

    <persistence-unit name="persistence.writing" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <non-jta-data-source>WritingDS</non-jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>

</persistence>

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'persistence.reading'定义了弹簧抛出。奇怪的是,看起来Spring尝试使用持久性单元名称实例bean
?我配置错误了吗?

更新 :当我unitName = "persistence.reading"从@PersistenceContext批注中删除时,我将得到以下错误:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: readingEntityManagerFactory,writingEntityManagerFactory

更新2 :Rohit建议(在评论中)连接EntityManagerFactory。因此,我尝试执行以下操作:

@PersistenceUnit(unitName = "persistence.reading")
private EntityManagerFactory emf;

但Spring仅报告: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'persistence.reading' is defined

最终修正 :感谢Vlad的回答,我能够更新代码以使用以下代码(只需确保还定义了dataSourcebean):

@Bean(name = "readingEntityManagerFactory")
public EntityManagerFactory readingEntityManagerFactory() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setPersistenceUnitName("persistence.reading");
    em.setDataSource(dataSource());
    em.setPackagesToScan("com.company");
    em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    em.afterPropertiesSet();
    return em.getObject();
}

问题答案:

的配置EntityManageFactory不正确。您应该LocalContainerEntityManagerFactoryBean改用:

@Bean(name = "readingEntityManagerFactory")
public EntityManagerFactory readingEntityManagerFactory() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setPersistenceUnitName("persistence.reading");
    em.setDataSource(dataSource());
    em.setPackagesToScan("com.company");
    em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    em.afterPropertiesSet();
    return em.getObject();
}

同样,它JpaTransactionManager也是配置错误的。应该是这样的:

@Bean(name = "readingTransactionManager")
public PlatformTransactionManager readingTransactionManager(){
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(readingEntityManagerFactory());
    return transactionManager;
}

对于读取和写入EntityManager配置,您都需要执行相同的操作。



 类似资料:
  • 最后的修正:由于Vlad的回答,我能够更新代码以使用以下内容(只需确保您还定义了bean):

  • 我有一个完全工作的Spring 4 Hibernate应用程序。Hibernate通过<代码> 我知道我可以定义一个像这样的bean,但不知道如何配置它。(我也不想重复配置。) MyTest.java test-context.xml 持久性.xml

  • 我有以下设置: EJB-JAR: 包含一些实体和DAO。 保存DAOS中使用的EntityManager的persistence.xml。 测试-战争: 包含一个servlet,它注入EJB-JAR的DAO之一(使用@inject或@ejb)。 问题是: > 我当前正在将应用程序部署到Wildfly 8.x 当我用一个在部署后启动的单例来部署jar时,我就能够按照预期使用DAOs。我正在从数据库得

  • 问题内容: 我尝试使用 多个线程 持久化对象时遇到问题。 细节 : 假设我有一个对象,该对象具有(一对多关系)列表,并且又包含(一对多关系)列表。 由于数量庞大(以十万计),我基于(基于某些业务逻辑)将其分组,并创建了 WORKER 线程(每个PaymentGroup一个线程)以形成对象并提交到数据库中。 问题是,每个工作线程都创建一个(包含唯一的一组)。 所有实体的主键都是自动生成的。 因此,存

  • 有没有办法将quarkus security jpa与多个持久性单元一起使用?JpaIdentityProvider似乎直接注入了实体管理器工厂,这导致了“javax.persistence.EntityManagerFactory类型的不满意依赖”的异常。 可能有解决办法吗? 有什么建议吗? 谢谢文森特

  • 包括我在内的一些人一直在努力将不同模块(JAR)中的实体合并到一个持久单元中(特别是使用JavaSE,例如这里的JPA2.0:自动将实体类添加到PersistenceUnit(来自不同的JAR)中)。基于这些答案,没有简单直接的方法可以做到这一点。解决方案之一是在单个持久性单元文件中列出所有JAR中的所有类,但这并不是很好。我可能无意中找到了另一条路。通常,我的所有实体类都使用注释进行映射。至于解