我有两个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
这当然是正确的,有两个EM bean,但由于我限制EM#1又称'entityManagerFactory'只打包'com.foo.repos.ora',我仍然不确定如何引用确切的EM bean。
答案 0 :(得分:13)
引擎盖下没有魔法。
<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直接注入实现类。 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'引用了标准JPA persistence.xml中的持久性
然而,2b)与'QueryDslRepositorySupport'不匹配,因为它需要一个EntityManager实例。但我发现'QueryDslRepositorySupport'无论如何都没有提供太多支持,所以我删除了它。