1. 概述

在这篇简短的文章中,我们将探讨如何解决Spring Data JPA抛出的异常PropertyReferenceException: No property found for type

首先,我们会解释这个异常的根本原因,然后通过实例展示如何复现它,最后讲解如何修复。

2. 原因

在深入细节之前,我们先尝试理解这个异常的含义。

堆栈跟踪中的“No property found for type”简单来说就是告诉我们找不到指定的属性。当Spring Data试图访问不存在或未定义的属性时,就会抛出这个异常。

通常情况下,Spring Data会根据衍生查询方法的名称自动生成SQL查询。因此,最常见的原因是定义了包含无效属性的查询方法

另一个原因可能是在访问属性时拼写错误了属性名。

3. 复现异常

现在我们了解了异常的含义,让我们看看如何在实践中复现它。

例如,考虑Person实体类

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String firstName;
    private String lastName;

    // standard getters and setters
}

接着,我们为Person类创建一个Spring Data JPA仓库:

@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
}

接下来,我们将添加一个按首名获取人的查询方法。然而,假设我们在编写时拼错了firstName属性。

例如,我们将它写成firsttName

Person findByFirsttName(String lastName);

现在如果我们启动Spring Boot应用,会看到如下错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository' defined in com.baeldung.nopropertyfound.repository.PersonRepository ...
...
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract com.baeldung.nopropertyfound.model.Person com.baeldung.nopropertyfound.repository.PersonRepository.findByFirsttName(java.lang.String)! 
No property 'firsttName' found for type 'Person'; Did you mean 'firstName'
...
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property 'firsttName' found for type 'Person'; Did you mean 'firstName'
...

如日志所示,Spring Boot因为找不到firsttName属性而失败。

Spring Data在启动时会自动检查生成的SQL查询是否有效

由于我们使用了一个不存在的属性(firsttName),Spring Data无法生成SQL查询,从而导致异常。

4. 解决方案

修复这个异常只有一个办法:在定义查询方法时使用确切的属性名称。

因此,要解决问题,我们需要将findByFirsttName()重命名为findByFirstName()

Person findByFirstName(String firstName);

现在,我们通过测试用例确认一切按预期工作:

@Test
void givenQueryMethod_whenUsingValidProperty_thenCorrect() {

    Person person = personRepository.findByFirstName("Azhrioun");

    assertNotNull(person);
    assertEquals("Abderrahim", person.getLastName());
}

如上所述,findByFirstName()查询方法没有失败,能正确返回按首名查找的人。

总之,为了避免PropertyReferenceException,请记住以下关键点:

  • 定义查询方法时使用精确的属性名称。
  • 避免使用缩写或拼写错误。
  • 双倍检查实体类,确保要引用的属性存在且拼写正确。
  • 使用带自动完成功能的代码编辑器,降低拼写错误的风险。
  • 为查询方法编写单元测试或集成测试,确保它们返回预期结果。

5. 总结

总的来说,我们详细讨论了Spring Data为何会抛出PropertyReferenceException: No property found for type的原因。

在过程中,我们通过实例展示了如何产生异常以及如何修复。如往常一样,示例的完整源代码可在GitHub上找到这里