web-dev-qa-db-ja.com

ページネーションを使用したSpringJPAリポジトリのカスタムクエリ

SpringBootで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);  
}

NamedQuery

<?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]に指定されたタイプは、クエリの戻り値のタイプ[classcom.mobicule.SpringBootJPADemo.beans.Employee]と互換性がありません。

SpringJPAリポジトリがカスタムメソッドとクエリに対しても提供するページネーション機能が欲しいだけです。どうすればこれを達成できますか?

6
ashish

理由はわかりませんが、何らかの理由でfrom Entityを実行すると「id」が返されます。代わりに、select f from Foo fのようにselectで返されるエンティティを指定する必要があります。

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ファイルに参照できると思います。 これが私の完全なコードです

さらにテストすると、from Foo fも機能することがわかります。エイリアスが必要な理由はわかりません。おそらく、JPQL仕様の一部です。

これは、単純なページング、1つのプロパティによる並べ替え、および複数のプロパティによる並べ替えを行う方法を示すテストです。

@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" ) );
}
5
xenoterracide