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



我正在使用带有 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 [pathtoSORepositoryImpl.class]
- soRepositoryImpl: defined in file [pathtoSORepositoryImpl.class]

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

您可以使用 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 
}

尝试从 SORepositoryImpl 类中删除@Repository注释

例如

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

错误消息暗示您有两个 bean,一个名为"qualifier",另一个名为"soRepositoryImpl",它可能在 Config 类中。

我想你应该分享你的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

好的,我发现了问题。

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

因此,当 Spring 尝试解决com.another.SORepository的所有依赖项时,它会以某种方式找到我的com.so.SORepositoryImpl(它与com.another.SORepository一无所知 - 不扩展\实现,不是 jpa 的东西,只有相似的名称!

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

我唯一应该做的是重命名'com.so.SORepositoryImpl,它不再有2个豆子了。

谢谢大家的回答!

最新更新