【问题标题】:Spring Data JPA: Repositories for multiple database / Entitymanger configurationsSpring Data JPA:多个数据库/实体管理器配置的存储库
【发布时间】:2013-05-09 03:24:06
【问题描述】:

我有两个Entitymanager bean 配置。每个都指向具有不同架构的单独数据库(一个是 Oracle,另一个是内存 H2)

我可以做些什么来解决每个存储库应该使用什么 Entitymanager 的歧义?现在我收到此错误:

 No unique bean of type [javax.persistence.EntityManagerFactory] is defined:
 expected single bean but found 2

我想我可以通过使用类似的东西来提供快速修复

<jpa:repositories base-package="com.foo.repos.ora"
 entity-manager-factory-ref="entityManagerFactoryA">

<jpa:repositories base-package="com.foo.repos.m2"
 entity-manager-factory-ref="entityManagerFactoryB">

但希望有更好的解决方案。

编辑:

我给你一个关于当前场景的想法:

Spring-Config:有两个 EM

<jpa:repositories base-package="com.foo.repos.ora" entity-manager-factory-ref="entityManagerFactory"/>
<jpa:repositories base-package="com.foo.repos.m2" entity-manager-factory-ref="entityManagerFactory2"/>
<context:component-scan base-package="com.foo" />  ....

从这里开始的所有内容都在“package com.foo.repos.ora”中 按照how to make a custom repository 的模式,我得到了两个接口'ARepository'、'ARepositoryCustom' 和它的实现'ARepositoryImpl',就像这样

@Repository
public interface ARepository extends ARepositoryCustom, JpaRepository<myEntity, BigDecimal>, QueryDslPredicateExecutor {

}

public interface ARepositoryCustom {
    FooBar lookupFooBar()
}

public class ARepositoryImpl extends QueryDslRepositorySupport implements ARepositoryCustom {
    ARepositoryImpl(Class<?> domainClass) {
        super(domainClass.class)
    }

    ARepositoryImpl() {
        this(myEntity.class)
    }

    @Override
    FooBar lookupFooBar() {
        JPQLQuery query = ....
        ....
        return found
    }
}

导致以下错误消息:

引起:org.springframework.beans.factory.BeanCreationException: 创建名为“aRepositoryImpl”的 bean 时出错:注入 持久性依赖失败;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 [javax.persistence.EntityManagerFactory] ​​类型的唯一 bean 是 定义:预期为单个 bean,但找到 2 个

这当然是正确的,有 2 个 EM bean,但由于我将 EM #1 aka 'entityManagerFactory' 限制为仅打包 'com.foo.repos.ora',我仍然不确定如何引用确切的EM 豆。

【问题讨论】:

    标签: entitymanager spring-data-jpa multiple-databases


    【解决方案1】:

    引擎盖下没有魔法。

    <jpa:repositories base-package="com.foo.repos.ora" entity-manager-factory-ref="entityManagerFactory"/>
    

    对您的自定义接口实现完全没有帮助。我发现的最佳方法是将您的自定义实现视为常规 bean。所以我在我的 spring 配置中定义了一个 'sharedEntitManager' bean,就像这样

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
           ...
    </bean>
    <bean id="sharedEntityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
            <property name = "entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    

    之后,我只是将 EntityManager 注入到我的实现 bean 中

    <bean id="aRepositoryImpl" class="comm.foo.repos.ora.ARepositoryImpl">
        <property name="entityManager" ref="sharedEntityManager"/>
    </bean>
    

    'entity-manager-factory-ref' 属性区分不同的实体管理器工厂,但仅适用于直接的 Spring Data Repositories(即仅适用于接口)。然而,它并不关心你的任何实现。

    总结一下

    1) 如果您只是依赖于没有自定义实现的标准 Spring Data 存储库,请使用“entity-manager-factory-ref”属性来区分数据库。

    2a) 此外,如果您使用任何自定义实现,请将适当的 EntityManager 直接注入到实现类中。布线是在您的 spring xml 配置的控制下完成的。由于某种原因,我无法将@Autowire 注释与@Qualifier 一起使用来引用正确的EntityManager。 编辑我刚刚了解了@Resource注解

    @Resource(name =  "sharedEntityManagerA")
    EntityManager entityManager
    
    
    <bean id="sharedEntityManagerA" name="sharedEntityManagerA" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
            <property name = "entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    

    有了这个,选择应该使用什么 EntityMANger 就变得很简单了。无需将所有内容都放在您的上下文 xml 中。

    2b) 作为 Spring 用于连接你的东西的 xml 配置的替代方案,你也可以使用

    @PersistenceContext(unitName = "nameOfPersistenceUnit")

    注入正确的EntitymanagerFactory

    而“nameOfPersistenceUnit”指的是您在标准 JPA persistence.xml 中的持久性

    但是 2b) 不适合“QueryDslRepositorySupport”,因为它需要一个 EntityManager 实例。但我发现 'QueryDslRepositorySupport' 并没有提供太多支持,所以我删除了它。

    【讨论】:

    • 2b) 如果你的应用程序上下文中有两个LocalContainerEntityManagerFactoryBeans,每个都有自己的persistenceUnitName,那么它也很有效。
    猜你喜欢
    • 2019-07-24
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多