Java 没有合格的bean,使用Spring数据JPA设置2个数据源
我正在尝试为我的项目设置第二个数据源。这是spring-context.xml:Java 没有合格的bean,使用Spring数据JPA设置2个数据源,java,spring,spring-boot,jpa,spring-data-jpa,Java,Spring,Spring Boot,Jpa,Spring Data Jpa,我正在尝试为我的项目设置第二个数据源。这是spring-context.xml: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="PERSISTENCECLASSES"/>
<!-- ************ JPA configuration *********** -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="firstTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="firstEntityManagerFactory" />
</bean>
<bean id="secondTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="secondEntityManagerFactory" />
</bean>
<bean id="firstEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:/persistence.xml" />
<property name="persistenceUnitName" value="second" />
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="DOMAINCLASSES" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
</bean>
</property>
</bean>
<bean id="secondEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="second" />
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="DOMAIN CLASSES" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
</bean>
</property>
</bean>
<bean id="userRepositoryImpl" class="PERSISTENCECLASSES.UserRepostoryImpl"/>
<bean id="first" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/first" />
<property name="resourceRef" value="true" />
</bean>
<bean id="second" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/second" />
<property name="resourceRef" value="true" />
</bean>
</beans>
我得到以下例外情况:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loadStartupData': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'PERSISTENCECLASSES.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 24 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'PERSISTENCECLASSES.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1654)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1213)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
... 42 more
LoadStartupData类是一个@服务
,它通过以下调用创建UserRepository的实例:
@Autowired UserRepository userrepo;
我的Spring应用程序:
@Configuration
@EnableScheduling
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@EnableTransactionManagement
public class App {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException, UnirestException {
SpringApplication.run(App.class, args);
}
}
任何关于如何修复它的想法,甚至是关于它可能来自何处的提示,都是高度赞赏的?
我试着使用@PersistenceContext、限定符和其他东西-但是没有任何效果。看起来与Spring数据的实际使用存在混淆(在引入第二个数据源之前的情况),在新的情况下,实际的存储库必须手动实现以服务于实际的crud操作 实际上有两种选择: i) 您所发布的尝试的一半,其中您必须为您需要的每个操作手动实现实际的查询调用,因此您不能真正使用Spring DATA提供的
JPARepository
。
在实际的impl类中,您将自动连接2个数据源并提供实际的服务调用
实际上,impl类如下所示
public class UserRepositoryImpl extends QuerydslRepositorySupport implements UserRepository {
@PersistenceContext(name = "firstEntityManagerFactory")
EntityManager firstEntityManagerFactory;
@PersistenceContext(name = "secondEntityManagerFactory")
EntityManager secondEntityManagerFactory;
//manually implement all crud operations , insert, delete, update, fetchByQuery plus your interface methods
Optional<User> findUserByEMail(String eMail);
Optional<User> findUserByUserName(String userName);
Optional<User> findUserByUserNameOrEMail(String userName, String eMail);
}
public类UserRepositoryImpl扩展QuerydslRepositorySupport实现UserRepository{
@PersistenceContext(name=“firstEntityManagerFactory”)
EntityManager FirstEntityManager工厂;
@PersistenceContext(name=“secondEntityManagerFactory”)
EntityManager第二EntityManager工厂;
//手动实现所有crud操作、插入、删除、更新、fetchByQuery以及接口方法
可选FindUserByMail(字符串电子邮件);
可选findUserByUserName(字符串用户名);
可选findUserByUserNameOrEMail(字符串用户名、字符串电子邮件);
}
您的界面将如下所示:
public interface UserRepository extends UserRepositoryCustom {
Optional<User> findUserByEMail(String eMail);
Optional<User> findUserByUserName(String userName);
Optional<User> findUserByUserNameOrEMail(String userName, String eMail);
}
public interface UserRepository扩展了UserRepositoryCustom{
可选FindUserByMail(字符串电子邮件);
可选findUserByUserName(字符串用户名);
可选findUserByUserNameOrEMail(字符串用户名、字符串电子邮件);
}
另外,如前所述,一些输入错误应该在spring-conf.xml中更正。(删除未使用的bean定义,映射到适当的实体包)
ii)检查此选项,以区分每个实体的数据源(如果适合您的情况)真的吗?spring-conf.xml中的输入错误?还有为什么会有第二个接口?你想达到什么目的?@AntJavaDev你在哪里发现打字错误?我试图建立两个数据库,每个数据库都有自己的存储库和域类。UserRepoCustom有一组UserRepoImpl实现的方法。我把它们放出来是为了呼吸。你确定这个bean存在吗??关于第二个接口的问题是,您试图自动连接第一个接口,但没有实现它,我想我错过了something@AntJavaDav第二个接口由第一个接口扩展。因此,用户Repo扩展了UserRepoCustom。据我所知,这是很常见的。另外,当我只有一个Spring自动配置的数据源时,它是这样工作的,所以我想这不是问题所在。关于bean,我遵循了一个教程:他们在spring-context.xmlhmm中为每个存储库提供了一个自己的bean,这很有趣,因此您建议实际的示例使用原始数据源,并且选择bean定义,因为您正在扩展同一个类。如果您是自动连接
UserRepositoryCustom
,这将是有意义的,如果您仔细阅读日志,这是实际的根本原因。另外,手动注册bean的尝试仍然会失败,因为我相信bean的类名是PERSISTENCECLASSES.UserRepositoryImpl
而不是PERSISTENCECLASSES.USerRepostoryImpl
感谢您的广泛回复!为什么我不能将JPARepositories与多个数据源一起使用?或者,您是否建议只有在没有自定义查询的情况下才能使用JPA或CRUD存储库?以及:既然您现在在UserRepo接口中定义自定义查询,UserRepo自定义接口会是什么样子?如果您选中第二个链接,您将看到,JPARepository
与特定的LocalContainerEntityManagerFactoryBean
通过“托管”实体紧密相连,这些实体只能使用一个数据源(至少我不知道其他任何有效方法)。设想一种情况,您希望通过第一个数据源插入一个新实体,但从第二个数据源更新或获取!?!Spring如何知道要通过实际实现呢!?还要检查这些答案以回答第二个问题,如果您的应用程序已经在调用spring data crud api,那么您必须手动覆盖定义到JPARepository的几乎所有方法(这可能很痛苦),否则您将实现自己的api,该api将传递到服务层。这仍然取决于你想要达到的目标!?也许只是适当的配置?某些存储库覆盖
@Configuration
@EnableScheduling
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@EnableTransactionManagement
public class App {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException, UnirestException {
SpringApplication.run(App.class, args);
}
}
public class UserRepositoryImpl extends QuerydslRepositorySupport implements UserRepository {
@PersistenceContext(name = "firstEntityManagerFactory")
EntityManager firstEntityManagerFactory;
@PersistenceContext(name = "secondEntityManagerFactory")
EntityManager secondEntityManagerFactory;
//manually implement all crud operations , insert, delete, update, fetchByQuery plus your interface methods
Optional<User> findUserByEMail(String eMail);
Optional<User> findUserByUserName(String userName);
Optional<User> findUserByUserNameOrEMail(String userName, String eMail);
}
public interface UserRepository extends UserRepositoryCustom {
Optional<User> findUserByEMail(String eMail);
Optional<User> findUserByUserName(String userName);
Optional<User> findUserByUserNameOrEMail(String userName, String eMail);
}