@Primary 等同于自动装配 Spring JPA 存储库

@Primary equivalent for autowired Spring JPA repositories

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

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

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

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

编辑 使事情更清楚: 假设我有一个实体 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 {
}

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

@Autowired
private ARepository repository;

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

我会根据这个答案改编这个想法: and this git example https://github.com/netgloo/spring-boot-samples/tree/master/spring-boot-springdatajpa-inheritance/src/main/java/netgloo/models

介绍一个标有@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,而且都是类型保存!

仅作记录,可以按照此处的建议添加 @Primary 对 JPA 存储库的支持 Using @Primary in Spring Data JPA repositories

我对缺失代码的实现:

private boolean isSpringDataJpaRepository(Class<?> beanClass) {
      return JpaRepositoryFactoryBean.class.isAssignableFrom(beanClass);
}

我认为@Ralph 的答案更好,因为类型安全。

Can I somehow tell Spring (via annotation on the repository or via configuration) which repository to use?

是的,你可以。首先,您给每个存储库 class 一个唯一的 bean 名称。

@Repository("myARepository")
public ARepository extends Repository<A, Long> {
}

@Repository("myBRepository")
public interface BRepository extends ARepository {
}

然后当您使用 ARepository 作为类型自动装配时,您应该使用 @Qualifier 注释来告诉 Spring 您想要哪个存储库。

@Autowire
@Qualifier("myBRepository")
private ARepository repository;

这将自动装配 BRepository