2013-05-14 179 views
11

我有兩個Entitymanager bean配置。每個數據庫都指向一個具有不同模式的獨立數據庫(一個是Oracle,另一個是內存中的H2)Spring Data JPA:多個數據庫/ Entitymanger配置的存儲庫

我該怎麼做才能解決Entitymanager應該用於每個Repository的模糊性?現在,我得到這個錯誤:

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的配置:這裏有兩種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「 按照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 
    } 
} 

導致以下錯誤消息:

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豆類,但因爲我限制EM#1又名 '的entityManagerFactory' 打包「com.foo .repos.ora',我仍然不確定如何引用確切的EM bean。

回答

13

引擎蓋下沒有魔法。

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

根本無法幫助您完成自定義界面的實施。我發現的最佳方式是將您的自定義實現視爲常規bean。所以,我在Spring配置中定義的「sharedEntitManager」豆像這樣

<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 id="aRepositoryImpl" class="comm.foo.repos.ora.ARepositoryImpl"> 
    <property name="entityManager" ref="sharedEntityManager"/> 
</bean> 

的「實體管理器工廠-REF」屬性會區分不同的實體管理工廠,但只能用於直接的Spring Data Repositories(即僅用於接口)。但它並不關心你的任何實現。

概括起來

1)如果單純依靠標準的Spring數據倉庫沒有定製的實現,使用「實體管理器工廠-REF」屬性來區分數據庫。另外,如果您使用任何自定義實現,則將相應的EntityManager直接注入到實現類中。 Wirering是在你的spring xml配置的控制下完成的。出於某種原因,我無法通過@Qualifier使用@Autowire註釋來引用正確的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」 referes到你的持久坐在

您標準JPA persistence.xml

但是2b)與'QueryDslRepositorySupport'不一致,因爲它需要一個EntityManager實例。但是我發現'QueryDslRepositorySupport'無論如何都沒有提供太多的支持,所以我刪除了它。

+0

2b)如果在應用程序上下文中有兩個'LocalContainerEntityManagerFactoryBean',每個都有它們自己的'persistenceUnitName',它也可以起到類似魅力的作用。 – 2013-08-13 13:23:13

相關問題