简体   繁体   English

没有合格的 bean,使用 Spring Data JPA 设置 2 个数据源

[英]No qualified bean, Setting up 2 data sources with Spring Data JPA

I am trying to set up a second data source for my project.我正在尝试为我的项目设置第二个数据源。 This is the spring-context.xml:这是 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="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>

My userRepo looks the following way:我的 userRepo 看起来如下:

public interface UserRepository extends JpaRepository<User, String>, UserRepositoryCustom {
    Optional<User> findUserByEMail(String eMail);
    Optional<User> findUserByUserName(String userName);
    Optional<User> findUserByUserNameOrEMail(String userName, String eMail);
}
public interface UserRepositoryCustom {}
public class UserRepositoryImpl extends QuerydslRepositorySupport implements UserRepositoryCustom {

    public UserRepositoryImpl() {
        super(User.class);
    }

    // Some QueryDSL methods
}

I am getting the following exception:我收到以下异常:

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

The LoadStartupData class is a @Service that creates an instance of UserRepository with the following call: LoadStartupData 类是一个@Service ,它通过以下调用创建 UserRepository 的实例:

@Autowired UserRepository userrepo;

My Spring App:我的春天应用程序:

@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);

    }

}

Any idea how to fix it or even a hint on where that might be coming from is highly appreciated?任何想法如何修复它,甚至是可能来自哪里的提示都受到高度赞赏? I tried using @PersistenceContext, Qualifiers and other things.我尝试使用@PersistenceContext、限定符和其他东西。 -nothing worked though. - 没有任何效果。

It looks like there is a confusion with the actual usage of Spring DATA(case before introducing a second datasource), and in the new case which the actual repository has to be manual implemented to serve the actual crud operations.看起来与 Spring DATA 的实际用法(引入第二个数据源之前的情况)存在混淆,在新情况下,必须手动实现实际存储库才能为实际的 crud 操作提供服务。

There are actually 2 options :实际上有2个选项:

i) Half of your posted attempt, in which you will have to manually implement the actual query calls for every operation you need so you cant really use the JPARepository offered by Spring DATA. i) 您发布的尝试的一半,您必须为您需要的每个操作手动实现实际的查询调用,因此您无法真正使用 Spring DATA 提供的JPARepository In the actual impl Class , you will autowire the 2 datasources and provide the actual service calls.在实际的 impl Class 中,您将自动装配 2 个数据源并提供实际的服务调用。

In reality the impl class would look like below实际上,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);
}

And your Interface would look like :你的界面看起来像:

public interface UserRepository extends UserRepositoryCustom {
    Optional<User> findUserByEMail(String eMail);
    Optional<User> findUserByUserName(String userName);
    Optional<User> findUserByUserNameOrEMail(String userName, String eMail);
}

Also some typos, as already mentioned, should be corrected in the spring-conf.xml.(remove unused bean definitions, map to the proper entity-packages)还有一些拼写错误,正如已经提到的,应该在 spring-conf.xml 中更正。(删除未使用的 bean 定义,映射到正确的实体包)

ii) Check this repository which distinguish the datasource by each entity (if that suits your case) ii)检查这个存储库,它区分每个实体的数据源(如果适合您的情况)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM