【问题标题】:Custom Query in Spring JPA Repository with Pagination带有分页的 Spring JPA 存储库中的自定义查询
【发布时间】:2015-10-29 16:53:32
【问题描述】:

我已经尝试使用 Spring Boot 实现 JPA 存储库,它工作正常。 现在,如果我尝试在使用@Query Annotation 扩展 JpaRepository 的接口中实现自定义查询,它可以正常返回 bean 列表。(使用 NamedQuery)。 现在,当我尝试将分页用于自定义方法/查询时,它不起作用。

代码:

控制器:

@RequestMapping("/custompages/{pageNumber}")
public String getAllEmployeesUsingNamedQueryWithPaging(@PathVariable Integer pageNumber,Model model)
{
    Page<Employee> page = employeeService.getAllEmployeesUsingNamedQueryWithPaging(pageNumber);

    System.out.println("current page "+page);
    System.out.println("current page content"+page.getContent());

     int current = page.getNumber() + 1;
    int begin = Math.max(1, current - 5);
    int end = Math.min(begin + 10, page.getTotalPages());

    model.addAttribute("empList", page.getContent());
    model.addAttribute("empPages", page);
    model.addAttribute("beginIndex", begin);
    model.addAttribute("endIndex", end);
    model.addAttribute("currentIndex", current);

    return "employeeWorkbench";
}

服务

@Override
public Page<Employee> getAllEmployeesUsingNamedQueryWithPaging(Integer  
pageNumber) {

    PageRequest pageRequest =
            new PageRequest(pageNumber - 1, PAGE_SIZE, 
    Sort.Direction.ASC, "id");
    return   
employeeDao.getAllEmployeesUsingNamedQueryWithPaging(pageRequest);
}

@Transactional
public interface EmployeeDao  extends JpaRepository<Employee, Long>{

@Query(name="HQL_GET_ALL_EMPLOYEE_BY_ID")//Works Fine
public List<Employee> getEmpByIdUsingNamedQuery(@Param("empId") Long
empId);     

@Query(name="HQL_GET_ALL_EMPLOYEE") //throws exception
public Page<Employee> getAllEmployeesUsingNamedQueryWithPaging(Pageable     
pageable);  
}

命名查询

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 
3.0//EN"  
"http://hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<query name="HQL_GET_ALL_EMPLOYEE">from Employee</query>

<query name="HQL_GET_ALL_EMPLOYEE_BY_ID">from Employee where id = 
:empId</query>

</hibernate-mapping>

异常:java.lang.IllegalArgumentException:指定的类型 TypedQuery [java.lang.Long] 与查询返回类型不兼容 [类 com.mobicule.SpringBootJPADemo.beans.Employee]

我只想让 Spring JPA Repository 为自定义方法和查询提供分页功能。 我怎样才能做到这一点?

【问题讨论】:

  • 如果不是在 xml 中使用命名查询,而是将查询直接放在 @Query("from Employee") 中,它会改变行为吗?存储库上的 @Transactional 也是多余的。同样对于这么简单的查询,您最好只使用存储库已有的findAll
  • 这个错误也暗示由于某种原因(对我来说并不明显)它认为指定的查询应该返回一个 Long 而不是Employees
  • @xenoterracide :感谢您的回复。我尝试使用简单的 @Query("from Employee") 但这将返回 List 而不是 Page。我的动机是使用 JpaRepositories 为我的自定义查询构建分页功能。正如你所说,我使用 findAll 可以正常工作,没有任何问题,甚至可以很好地用于分页。但我也希望我的自定义查询具有相同的功能。
  • 我已经搜索了这个查询,我知道当 JpaRepository 执行它的方法 findAll,findBy......etc 并进行分页时,它会运行 2 个查询 --- 一个用于计数,另一个用于实际数据.
  • 是的,计数是故意的......所以它知道它有多少页。如果返回类型指定为Page&lt;Employee&gt;,则不应获取List,只有在请求List或List的子接口(例如Iterable)时才应获取List

标签: hibernate spring-mvc spring-boot spring-data-jpa data-paging


【解决方案1】:

我不知道为什么,但出于某种原因,简单地执行 from Entity 会导致返回“id”,而您需要提供选择中返回的实体,例如 select f from Foo f

public interface FooRepo extends PagingAndSortingRepository<Foo, Long> {

@Query( "select f from Foo f" )
Page<Foo> findAllCustom( Pageable pageable );

Page<Foo> findAllByBarBazContaining( String baz, Pageable pageable );
}

我收到了同样的错误,只有from Foo。我也相信您可以像以前一样按名称将这些引用到 xml 文件中。 here's my full code

进一步测试表明from Foo f 也可以,我不知道为什么需要别名,也许它是 JPQL 规范的一部分。

这是一个测试,展示了如何进行简单的分页,按一个属性排序和按多个属性排序

@Test
public void testFindAllCustom() throws Exception {
    Page<Foo> allCustom = fooRepo.findAllCustom( pageable );

    assertThat( allCustom.getSize(), is( 2 ) );

    Page<Foo> sortByBazAsc = fooRepo.findAllCustom( new PageRequest( 0, 2, Sort.Direction.ASC, "bar.baz" ) );

    assertThat( sortByBazAsc.iterator().next().getBar().getBaz(), is( "2baz2bfoo" ) );

    Page<Foo> complexSort = fooRepo.findAllCustom( new PageRequest( 0, 2, new Sort(
            new Sort.Order( Sort.Direction.DESC, "bar.baz" ),
            new Sort.Order( Sort.Direction.ASC, "id" )
    ) ) );

    assertThat( complexSort.iterator().next().getBar().getBaz(), is( "baz1" ) );
}

【讨论】:

  • 更改查询有效。现在我也可以为自定义查询提供 Jpa 分页功能。谢谢 !!!干杯....!!!!
  • 您应该将此作为您接受的答案,点赞也不错
  • @xenoterracide 请看这个..stackoverflow.com/questions/32434058/…
  • @NadeemAhmed 如果这行得通,除了“错误”之外,它并不能真正解释这里发生了什么。我有各种工作分页规范和@Query 以及简单的方法解析器。我只能说,我也得到了提问者帖子中描述的异常。
  • 好的,我发现了问题,这很奇怪。主查询有点复杂,有几个内部和左获取连接。我将查询和计数查询都写为 select f from foo...;现在,如果我对 mysql 运行它,查询工作正常。相反,h2db 需要“从 foo 中选择 count(f)”作为计数查询。希望这会有所帮助
猜你喜欢
  • 2021-01-04
  • 2017-11-15
  • 1970-01-01
  • 2019-06-17
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-02
  • 2020-01-07
相关资源
最近更新 更多