@Primary 相当于自动装配的 Spring JPA 存储库 [英] @Primary equivalent for autowired Spring JPA repositories

查看:32
本文介绍了@Primary 相当于自动装配的 Spring JPA 存储库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在应用程序中使用 Spring JPA 存储库和实体.现在,在该应用程序的一种风格中,我需要扩展我的一个实体并提供一个扩展的存储库.

I use Spring JPA repositories and entities in an application. Now, in a flavor of that application, I need to extend one of my entities and also provide an extended repository.

对于我需要覆盖/扩展的所有其他 bean,我只需创建一个新实现并使用 @Primary 对其进行注释,这样它将自动装配而不是默认实现.

For all other beans I need to override/extend I simply create a new implementation and annotate it with @Primary so it will be autowired instead of the default implementation.

但是,对于存储库,这不起作用.我可以用@Primary 注释新的存储库,但它没有效果(两个 bean 都被找到,因此不能自动装配).这是有道理的,因为存储库是一个接口而不是一个实现,实现是由 Spring 动态提供的.

For repositories, however, this does not work. I can annotate the new repository with @Primary but it has no effect (both beans are found and can thus not be autowired). This makes sense because the repository is an interface and not an implementation, the implementation is provided by Spring dynamically.

我能否以某种方式告诉 Spring(通过存储库上的注释或通过配置)使用哪个存储库?或者我是否必须像这样手动解决在 Spring Data JPA 中使用 @Primary存储库 还是我应该想出一种存储库提供程序而不是自动装配?

Can I somehow tell Spring (via annotation on the repository or via configuration) which repository to use? Or do I have to do a manual workaround like this Using @Primary in Spring Data JPA repositories or should I come up with a kind of repository provider instead of autowiring?

编辑以使事情更清楚:假设我有一个实体 A

Edit to make things clearer: Let's say I have an entity A

@Entity
public class A {
  @Id
  private long id;
}

及其存储库

public ARepository extends Repository<A, Long> {
}

现在我将它扩展到实体B

@Entity
public class B extends A {
}

public interface BRepository extends ARepository {
}

通常,根据文档,您使用这样的存储库:

Normally, as per the documentation, you use repositories like this:

@Autowired
private ARepository repository;

然而,这不起作用,因为现在有两个 ARepository 类型的 bean.对于我自己实现的 bean,我会在扩展类上使用 @Primary 但对于存储库,在编译时没有接口的实现.

This does, however, not work because there are now two beans of the type ARepository. For beans that I implement myself I would use @Primary on the extending class but for repositories there is no implementation of the interface at compile time.

推荐答案

我会根据这个答案调整想法:https://stackoverflow.com/a/27549198/280244 和这个 git 示例 https://github.com/netgloo/spring-boot-samples/tree/master/spring-boot-springdatajpa-inheritance/src/main/java/netgloo/models

I would adapt the idea form this answer: https://stackoverflow.com/a/27549198/280244 and this git example https://github.com/netgloo/spring-boot-samples/tree/master/spring-boot-springdatajpa-inheritance/src/main/java/netgloo/models

引入一个通用的抽象Repository,标记为@NoRepositoryBean

Introduce a common abstract Repository that is marked with @NoRepositoryBean

@NoRepositoryBean
public interface AbstractARepository<T extends A>
                                    extends Repository<T, Long> {
    T findByName(String name); //or what ever your queries are
}

public ARepository extends AbstractARepository<A> {
   //almost emtpy
}


public BRepository extends AbstractARepository<B> {
   //queries that are special for B
}

现在你可以注入ARepositoryBRepository,并且都是type save!

Now you can inject ARepository and BRepository, and both are type save!

这篇关于@Primary 相当于自动装配的 Spring JPA 存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆