Java JpaSpecificationExecutor<;T>;似乎不像JpaRepository那样出色<;T、 I>;

Java JpaSpecificationExecutor<;T>;似乎不像JpaRepository那样出色<;T、 I>;,java,spring,spring-boot,jpa,Java,Spring,Spring Boot,Jpa,通常在使用JpaRepository接口时,我倾向于提及接口中的方法,这些方法将在我的服务类中使用。例如: public interface UserRepository extends JpaRepository<User, Integer> { List<User> findAll(); // Usually I mention the methods this way in the interface. } public interface UserR

通常在使用JpaRepository接口时,我倾向于提及接口中的方法,这些方法将在我的服务类中使用。例如:

public interface UserRepository extends JpaRepository<User, Integer> {

    List<User> findAll(); // Usually I mention the methods this way in the interface.

}
public interface UserRepository扩展了JpaRepository{
List findAll();//通常我在接口中这样提到方法。
}
这是完美的。然而,当使用JpaSpecificationExecutor接口时,如果我提到接口中的方法,它会抛出错误,如-未能创建查询方法

如果我不提及该方法,它将按预期工作。有人能解释一下春天这种奇怪的行为吗

public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {

    List<User> findAll(UserSpecification user); // If I do not mention this method here, it works perfectly.

}
public interface UserRepository扩展了JpaRepository,JpaSpecificationExecutor{
List findAll(UserSpecification user);//如果我在这里没有提到这个方法,那么它可以完美地工作。
}
  • List findAll()
    在一个扩展接口(即
    JpaRepository
    )中声明。如果签名相同,在扩展接口中重新声明方法不是错误;它根本没有任何效果。这一事实与Spring数据无关;这就是Java的工作原理

  • List findAll(用户规范)
    未在任何扩展接口中声明。请注意,通过实现
    JpaSpecificationExecutor
    ,您的接口将继承一个带有签名
    List findAll(Specification)
    的方法声明,该签名与不同。这两种方法具有不同的签名,因为
    Specification
    UserSpecification
    的类型不同

  • 当然,您可以将新方法添加到存储库接口,只要它们表示简单的查询,而不使用
    规范
    参数,例如
    用户findByName(字符串名)
    ,Spring数据将在运行时自动生成这些方法的实现

  • 如果新方法的参数表示扩展
    规范的自定义类型,或者Spring数据无法识别的任何其他类型,则无法向存储库接口添加新方法,因为在运行时,Spring数据将无法为这种方法生成一个实现——它根本不知道如何处理这种方法


  • 对于规范,您应该使用
    JpaSpecificationExecutor
    提供的方法。我也不明白你为什么想要像
    List findAll(UserSpecification user)
    这样的方法——如果
    UserSpecification
    扩展
    Specification
    ,那么继承的
    List findAll(Specification)
    就可以正常工作了

    因为规范封装并替换了您通常使用spring数据“域特定语言”作为存储库方法提到的显式条件。如果您看一下文档(),您会发现这个接口已经包含了所有这些您通常会显式写下的方法,但JpaRepository接口也是如此。显然,JpaRepository只涵盖了JpaRepository接口中的基本情况,findAll()方法在Jpa接口中可用,但在明确提到它之后,它仍然有效。我有点困惑。