Spring Data JPA:多个数据库/ Entitymanger配置的存储库 [英] Spring Data JPA: Repositories for multiple database / Entitymanger configurations

查看:110
本文介绍了Spring Data JPA:多个数据库/ Entitymanger配置的存储库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two Entitymanager bean configurations. Each pointing to a separate database with a different schema (one is Oracle, the other one is an in-memory H2)

我该怎么做才能解决模棱两可的问题每个存储库都应使用Entitymanager?现在,我收到此错误:

What could I do to solve the ambiguity of what Entitymanager should be used for each Repository? Right now I'm getting this error:

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

我想我可以通过使用某些东西来提供快速修复像

I guess I could provide a quick-fix simply by using something like

<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">

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

But hopefully there is a better solution.

编辑:

我为您提供了当前情况的提示:

I give you an idea of the current scenario:

Spring-Config:有两个EM

Spring-Config: there're two 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" />  ....

这里的所有内容都在包com.foo.repos.ora中b $ b遵循如何创建自定义存储库的模式我得到两个接口 ARepository, ARepositoryCustom及其实现 ARepositoryImpl,就像这样

Everything from here on is in "package com.foo.repos.ora" Following the pattern of how to make a custom repository I get two interfaces 'ARepository', 'ARepositoryCustom' and its implementation 'ARepositoryImpl' like so

@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]的
个唯一豆没有定义为
期望单个豆但找到了2

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'aRepositoryImpl': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 2

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

Which is of course correct, there are 2 EM beans, but since I restricted EM #1 aka 'entityManagerFactory' to package 'com.foo.repos.ora' only, I'm still not sure how to reference the exact EM bean.

推荐答案

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

自定义界面实现根本无法帮助您。我发现的最好方法是将您的自定义实现视为常规bean。所以我在春季配置中定义了一个'sharedEntitManager'bean,

doesn't help you at all with your custom interface implementations. Best way I found is to treat your custom implementations as regular beans. So I defined a 'sharedEntitManager' bean in my spring configuration like so

<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中

After that, I simply injected the EntityManager into my implementation beans

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

'entity-manager-factory-ref'属性区分不同的实体管理器工厂,但仅适用于直接Spring数据存储库(即仅用于接口)。但是,它与您的任何实现都不相关。

The 'entity-manager-factory-ref' attribute discriminates between different entitymanager factories but only for straight Spring Data Repositories (i.e. only for interfaces). It doesn't however concern itself with any of your implementations.

总结一下

1)如果您只需依靠没有自定义实现的标准Spring Data存储库,就可以使用 entity-manager-factory-ref属性来区分数据库。

1) if you simply rely on standard Spring Data repositories with no custom implementation, use the "entity-manager-factory-ref" attribute to differentiate databases.

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

2a) Additionally, if you use any custom implementation, inject the appropriate EntityManager directly into the implementing class. Wirering is done under control of your spring xml configuration. For some reason I wasn't able to use the @Autowire annotation with a @Qualifier to reference the correct EntityManager. EDIT I just learned about the @Resource annotation

@Resource(name =  "sharedEntityManagerA")
EntityManager entityManager


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

有了这个,选择应使用的EntityMAnger变得很简单。

With this at hand selecting what EntityMAnger should be used becomes straightforward. No need of plumbing everything togehther in your context xml.

2b)作为Spring xml配置的替代选择,您也可以使用

2b) As an alternative to Spring's xml configuration for hooking up your stuff you may also go with


@PersistenceContext(unitName = nameOfPersistenceUnit)

@PersistenceContext( unitName = "nameOfPersistenceUnit" )

到注入正确的EntitymanagerFactory

to inject the correct EntitymanagerFactory

而'nameOfPersistenceUnit'是指您位于标准JPA persistence.xml中的持久性

While 'nameOfPersistenceUnit' referes to your persistence sitting in your standard JPA persistence.xml

但是2b)与'QueryDslRepositorySupport'配合不太好,因为它需要EntityManager实例。但是我发现‘QueryDslRepositorySupport’并不能提供太多支持,所以我删除了它。

However 2b) doesn't go well with 'QueryDslRepositorySupport', since it expects an EntityManager instance. But I found that 'QueryDslRepositorySupport' doesn't offer much support anyway, so I removed it.

这篇关于Spring Data JPA:多个数据库/ Entitymanger配置的存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆