简体   繁体   中英

Spring data JPA nativeQuery order by is invalid

The Spring Data Jpa Method like this:

@Query("select pb.id,pp.max_borrow_amt,pp.min_borrow_amt
from product_loan_basic pb left join product_loan_price pp on pb.code=pp.product_code 
 where pb.code IN(?1) and pb.status='publish' order by  ?2 ",
nativeQuery = true)  
List<Object[]> findByCodesIn(List<String> codes,String orderby);

Dynamic sorting in Spring Data JPA

If you used a JPA query you could use Sort as an argument of your query method to define the sorting order:

@Query("select m from Model m")
List<Model> getSortedList(Sort sort);

and then, for example:

List<Model> models = getSortedList(Sort.by(Sort.Direction.DESC, "name"));

But Spring Data JPA can't use Sort with native queries:

Spring Data JPA does not currently support dynamic sorting for native queries, because it would have to manipulate the actual query declared, which it cannot do reliably for native SQL.

However you can use Pageable and its implementation PageRequest instead:

@Query(value = "select m.name as name from models m", nativeQuery = true)
List<ModelProjection> getSortedList(Pageable p);

and then:

List<ModelProjection> modelNames = getSortedList(PageRequest.of(0, 1000, Sort.Direction.DESC, "name"));

PS Instead of array of Object s as returned parameters, it's better to use projections , for example:

public interface ModelProjection {
    String getName();
}

Note that in this case the good practice is to use aliases in queries (ie m.name as name ). They must match with correspondent getters in the projection.

Working demo and test .

Thanks everyone! my problem has been solved.

if you want to use Spring data jpa nativeQuert & Sort,you should do like this:

@Query( value ="select pb.id,pp.max_borrow_amt from product_loan_basic pb left join product_loan_price pp on pb.code=pp.product_code ORDER BY ?#{#pageable} ", countQuery = "select count(*) from product_loan_basic", nativeQuery = true ) Page findAllProductsAndOrderByAndSort(Pageable pageable);

?#{#pageable} is required and countQuery is required.

Pageable pageable = new PageRequest(0,1000,Sort.Direction.DESC,"id");

then result is sorted

see Spring Data and Native Query with pagination

I couldn't use @Param

 Page<Object[]> findAllUsersdSort(@Param("firstName")String firstName,@Param("lastName")String lastName
  Pageable pageable);

It complained about

Mixed parameter strategies - use just one of named, positional or JPA-ordinal strategy

I had to use:

Page<Object[]> findAllUsersdSort(String firstName, String lastName, Pageable pageable);

I couldn't get it working for H2 only. Not sure if I need to physical DB or not.

I added ?#{#pageable} in the 1st place.

  @Query(
  value ="select * from person where firstName = ?1 and lastName = ?2  ORDER BY ?#{#pageable} ",nativeQuery = true)  

It gave this this error:

"could not prepare statement; SQL [select * from person where firstName = ? and lastName = ? ORDER BY ? , lastName desc, id desc]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement"

Then I tried removing ORDER BY ?#{#pageable} and used only

 @Query(
  value ="select * from person where firstName = ?1 and lastName = ?2",nativeQuery = true) 

It gave me new error

"could not prepare statement; SQL [select * from person where firstName = ? and lastName = ?  order by lastName desc, id desc limit ?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement"

Not sure where that limit ? comes from?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM