Spring Boot检测到2个相同的存储库bean

时间:2016-12-13 14:10:46

标签: spring spring-boot spring-data spring-data-jpa

我在Spring Data JPA中使用Spring Boot,只有一个@SpringBootApplication。我还有一个存储库类,例如:

package com.so;
public interface SORepository {
    //methods
}

并且impl

@Repository("qualifier")
@Transactional(readOnly = true)
public class SORepositoryImpl implements SORepository {
   //methods
}

问题是,当我启动应用程序时,我收到以下错误:

Parameter 0 of constructor in com.so.SomeComponent required a single bean, but 2 were found:
    - qualifier: defined in file [path\to\SORepositoryImpl.class]
    - soRepositoryImpl: defined in file [path\to\SORepositoryImpl.class]

因此,正如您所看到的,以某种方式创建了一个存储库类的2个bean。我该如何解决这个问题?

4 个答案:

答案 0 :(得分:1)

您可以使用已创建Proxy元素的Spring Data JPA方法,然后将其注入公共类SORepositoryImpl:

public interface Proxy() extends JpaRepository<Element, Long>{
     Element saveElement (Element element); //ore other methods if you want}

而不是:

@Repository
@Transactional(readOnly = true)
public class SORepositoryImpl implements SORepository {

@Autowired
private Proxy proxy;

   //end realisation of methods from interface SORepository 
}

答案 1 :(得分:0)

尝试从SORepositoryImpl类中取出@Repository注释

e.g。

@Transactional(readOnly = true)
public class SORepositoryImpl implements SORepository {
   //methods
}

错误消息暗示您有两个bean,一个名为&#34;限定符&#34;和一个名为&#34; soRepositoryImpl&#34;,可能在Config类中。

答案 2 :(得分:0)

我猜你应该分享你的SomeComponent类,假设你没有额外的配置类/ xml。我的看法是你在'soRepositoryImpl'注入你定义为'限定符'的地方。有两种选择。我会说只是删除注释参数'限定符',它应该工作。

此外,除非您想要指定自定义DAO实现,否则您可以完全避免使用@Repository(这是您用来为服务注入的注释)。您可以创建一个扩展Spring接口的接口并定义查询方法。

例如:

public interface PersonRepository extends Repository<User, Long> {

  List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname); 

然后你可以直接将它注入你的服务/控制器。

  private final PersonRepository personRepository;
  public PersonController(final PersonRepository personRepository) {
    this.personRepository = personRepository;
  }

检查样品: https://spring.io/guides/gs/accessing-data-jpa/

http://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html

答案 3 :(得分:0)

好的,我发现了这个问题。

我无法理解Spring是如何创建第二个bean(soRepositoryImpl)的,因为我从来没有告诉它,既没有显式也没有在配置类中。但我发现我们在另一个SORepository实例化期间创建了第二个bean(它位于不同的包com.another中,并扩展了JpaRepository)。

所以,当Spring尝试解决com.another.SORepository的所有依赖关系时,它会以某种方式找到我的com.so.SORepositoryImpl(对com.another.SORepository没有任何熟悉 - 没有扩展\实现,而不是jpa的东西,只有类似的名!)。

对我来说这似乎是一个Spring bug,因为它不会检查依赖类存储库的真正继承,只有name + Impl(即使在不同的包中)才适合他。

我应该做的唯一事情就是重命名`com.so.SORepositoryImpl并且它不再是2个bean。

谢谢大家的回答!