Spring + JPA +多个持久性单元:注入EntityManager

我需要使用一个数据库进行查询(非修改),一个用于命令(修改)。 我使用的是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中定义的持久性单元名称:

   org.hibernate.jpa.HibernatePersistenceProvider ReadingDS       org.hibernate.jpa.HibernatePersistenceProvider WritingDS       

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

更新 :当我从@PersistenceContext注释中删除unitName = "persistence.reading" ,我将收到以下错误: 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的回答,我能够更新代码以使用以下内容(只需确保定义dataSource bean):

 @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配置执行相同的操作。