找不到类型的属性...自定义 Spring 数据存储库

Posted

技术标签:

【中文标题】找不到类型的属性...自定义 Spring 数据存储库【英文标题】:No property found for type... custom Spring Data repository 【发布时间】:2017-05-18 23:37:47 【问题描述】:

我正在尝试实现一个自定义 Spring 存储库。我有接口:

public interface FilterRepositoryCustom 
    List<User> filterBy(String role);

实施:

public class FilterRepositoryImpl implements FilterRepositoryCustom 
...

和“主”存储库,扩展我的自定义存储库:

public interface UserRepository extends JpaRepository<User, String>, FilterRepositoryCustom 
...

我正在使用 Spring Boot,根据docs:

默认情况下,Spring Boot 将启用 JPA 存储库支持并查看 @SpringBootApplication 所在的包(及其子包) 位于。

当我运行我的应用程序时,我得到了这个错误:

org.springframework.data.mapping.PropertyReferenceException: No property filterBy found for type User!

【问题讨论】:

【参考方案1】:

这里的问题是您正在创建 FilterRepositoryImpl,但您在 UserRepository 中使用它。您需要创建 UserRepositoryImpl 来完成这项工作。

Read this doc for more detail

基本上

public interface UserRepositoryCustom 
    List<User> filterBy(String role);


public class UserRepositoryImpl implements UserRepositoryCustom 
...


public interface UserRepository extends JpaRepository<User, String>, UserRepositoryCustom 
...

Spring Data 2.x 更新 这个答案是为 Spring 1.x 编写的。正如Matt Forsythe 所指出的,命名期望随着 Spring Data 2.0 的变化而改变。实现从the-final-repository-interface-name-with-an-additional-Impl-suffix 更改为the-custom-interface-name-with-an-additional-Impl-suffix

所以在这种情况下,实现的名称是:UserRepositoryCustomImpl

【讨论】:

虽然我同意这是可行的(并且已经看到了它的实际效果),但我很难将此行为与链接文档相协调,该文档在名为 @987654332 的存储库上明确使用了 CustomizedUserRepositoryImpl @。然后文档进一步(示例 29)在 UserRepository 上一起使用 HumanRepositoryImplContactRepositoryImpl。它们似乎表明重要的是片段实现名称与片段接口名称匹配,而不是基本存储库名称,但从我所看到的情况显然不是这样。我很困惑... 做了更多的挖掘并回答了我自己的问题:实现名称基于基本存储库名称的要求仅适用于旧 (1.x) 版本的 spring-data。在 spring-data 的 2.x 版本中,这个要求发生了变化。在 2.x 中,impl 名称必须跟在自定义接口名称之后。 你节省了我的时间,让我很开心!谢谢,用 Spring Data 命名真的很重要,测试事件。 还有 xxxRepository 和 xxxRepositoryImpl 的包也很重要。如果 xxxRepository 在 com.test 包中,那么 xxxRepositoryImpl 应该在 com.test.impl Spring 文档中的相同问题:docs.spring.io/spring-data/jpa/docs/current/reference/html/… CustomizedUserRepository、CustomizedUserRepositoryImpl 和 UserRepository,但它不起作用,因为 CustomizedUserRepositoryImpl 应该是 UserRepositoryImpl 感谢您的解决方案。【参考方案2】:

如果在您的 spring 配置中未选择 FilterRepositoryCustom 的 impl 类,则会发生此错误的另一种方式:

@EnableJpaRepositories(basePackageClasses = RepoPackageMarker.class, FilterRepositoryCustomImpl.class)

【讨论】:

【参考方案3】:

CustomRepository 中的customMethod() 是否必须只能定义以下任一参数

1.实体类名-customMethod(User user),

2.Entity类属性-customMethod(String firstName),这里firstName是User Entity类的一个属性。

我能不能有一些类似customMethod(CustomCriteria criteria)的东西,标准类包含用于构造动态查询的各种属性。

例如getStatusByCriteria(CustomCriteria criteria), CustomCriteria 是一个简单的 pojo,用 @Component 注解,以便 spring 识别它。

当我尝试这个时,我得到一个错误:

org.springframework.data.mapping.PropertyReferenceException: 否 找到类型 UserRepository 的属性条件!

【讨论】:

【参考方案4】:

我遇到了同样的问题。请检查您的包结构是否如下所示

custom
   impl
      - FilterRepositoryCustomImpl.class
- FilterRepositoryCustom.class      

因为当我尝试使用我的自定义存储库时,它看不到实现。 (实现应该在同一个包或者子包中让Spring看到)

也许它可以帮助某人(ノ^∇^)

【讨论】:

"实现应该在同一个包或子包中,让Spring看到它"非常有用。谢谢。【参考方案5】:

对我来说,钥匙是

    @EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class) 接口上的@NoRepositoryBean注解

按照您的春季版本的文档 https://docs.spring.io/spring-data/data-commons/docs/2.3.4.RELEASE/reference/html/#repositories

结果我有:

@NoRepositoryBean
public interface SliceRepository<T, ID> extends JpaRepository<T, ID> ..

public class SliceRepositoryImpl<T, ID> extends SimpleJpaRepository<T, ID> implements SliceRepository<T, ID> ..


@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactory",
        basePackages = "com.some.servicename.repository",
        repositoryBaseClass = SliceRepositoryImpl.class
)

【讨论】:

【参考方案6】:

我也有这个错误。发生这种情况是因为我已经使用包配置了 elasticSearch 存储库

@EnableElasticsearchRepositories("some.package")

接下来我将 MyElasticSearchRepository 从包 'some.package' 移动到另一个,但没有更改配置

【讨论】:

【参考方案7】:

我在我的一个项目中遇到了同样的问题。我通过在 pom.xml

中添加一行来解决问题
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <includes>
            <include>com/my/package/entities/*.java</include>
            <include>com/my/package/repositories/*.java</include>
            <include>com/my/package/repositories/impl/*.java</include> <!-- add this -->
        </includes>
    </configuration>
</plugin>

【讨论】:

【参考方案8】:

与片段接口对应的类名中最重要的部分是Impl后缀。

【讨论】:

【参考方案9】:

老办法:

Entity aThing = repository.findOne(1L);

新方法:

Optional<Entity> aThing = repository.findById(1L);

【讨论】:

欢迎来到 Stack Overflow。虽然此代码可能会回答问题,但提供有关此代码回答问题的原因和/或方式的附加上下文会提高其长期价值。How to Answer

以上是关于找不到类型的属性...自定义 Spring 数据存储库的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot jdbc模板在自定义模式下的postgres中找不到表

Spring Data JPA - “找不到类型的属性”异常

在“UITableViewCell”类型的对象上找不到属性

带有 MyBatis 的 Spring Data JDBC 找不到自定义查询

在 Spring Boot 应用程序中找不到类型现金流的属性日期

Spring Boot JPA 错误:无法处理托管/反向引用“defaultReference”:从类型中找不到反向引用属性