从方法名称禁用查询创建 - 使用投影

时间:2017-09-14 15:51:11

标签: spring-data spring-data-jpa

我想使用Spring Data Projection技术,只从表中提取一些字段(而不是表格的所有字段)。

如文档(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections)中所述,我创建了一个简单的界面,例如:

interface NamesOnly {
  String getFirstname();
  String getLastname();
}

但我使用它有一些问题。

问题1:

首先,我想使用名称findAll()创建一个查询,查找只包含两个字段(firstNamelastName)的所有行:

@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
    List<NamesOnly> findAll();
}

但是在这种情况下我有这些错误(可能是因为findAll()JpaRepository的方法):

  
      
  • 实现org.springframework.data.jpa.repository.JpaRepository.findAll
  •   
  • 返回类型与JpaRepository.findAll()
  • 不兼容   

问题2:

好的,我尝试将方法的名称更改为findAllOnlyNames()

@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
    List<NamesOnly> findAllOnlyNames();
}

但现在我有这个错误:

  

引起:   org.springframework.data.mapping.PropertyReferenceException:没有   找到类型为Persona的属性findAllOnlyNames!

因为Spring尝试从名称创建查询。

1)是否可以在没有JpaRepository问题的情况下重用方法名findAll()

2)是否可以从方法名称关闭查询创建(仅针对某些查询,而不是针对所有项目或存储库)?

2 个答案:

答案 0 :(得分:3)

您走在正确的轨道上,您的findAll()与现有Spring Data接口上指定的@Repository public interface PersonaRepository extends JpaRepository<Persona, Long> { List<NamesOnly> findAllOnlyNamesBy(); } 冲突,您可以重命名它(如您所尝试的那样),但它仍然必须是兼容的名称使用查询派生机制。试试这个:

find…By

This part of the Spring Data JPA documentation解释了查询创建过程的工作原理:

  

该机制从方法中删除前缀read…Byquery…Bycount…Byget…ByBy,然后开始解析其余部分。< / p>

因此,您只需要在方法名称中添加@Query(...)关键字,将该关键字视为条件后的任何内容,在这种情况下,没有条件,因此它会获取所有内容。

要从方法名称禁用查询派生,您需要向方法添加Object注释,并指定JPA或本机查询。

答案 1 :(得分:2)

您可以指定显式查询,而不是依赖于从方法名称派生它。

@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
    @Query("select p from Persona p")
    List<NamesOnly> findAllOnlyNames();
}

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query

覆盖findAll()(即使在不太可能发生的情况下)也可能是一个坏主意。