Проблема, когда я пытаюсь использовать оператор Case в JPQL

#java #spring-boot #jpql

#java #весенняя загрузка #jpql

Вопрос:

Здравствуйте, я пытаюсь реализовать запрос (который содержит оператор case) из отдела базы данных, но я не мог понять, в чем проблема.

 @Query("select new com.withgratitude.api.core.domain.ReportTopTenBiddersTable( CONCAT(u.firstName, ' ', u.lastName), "  
           "b.auctionId, b.date), "  
           " case when (b.isTheWinner = 0) then 'No' when (b.isTheWinner = 1) then 'Yes' else 'No Winner' end as winnerBid"  
           "                        from Bids b, Users u "  
           "                       where b.userId = u.userId "  
           "                       order by CONCAT(u.firstName, ' ', u.lastName)")
   List<ReportTopTenBiddersTable> reportTopTenBiddersTable();


  
 Here is the Query I am trying to implement:
#top 10 bidders - table
select CONCAT(u.first_name, ' ', u.last_name) as name, b.auction_id, b.date, 
                              case b.is_thewinner when 0 then 'No' when 1 then 'Yes' end as WinnerBid, b.offer
                       from bids b, users u 
                       where b.user_id = u.user_id
                       order by name
                       limit 10;
  
 Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: , near line 1, column 130 [select new com.withgratitude.api.core.domain.ReportTopTenBiddersTable( CONCAT(u.firstName, ' ', u.lastName), b.auctionId, b.date),  case when b.isTheWinner = 0 then 'No' when b.isTheWinner = 1 then 'Yes' else 'No Winner' end as winnerBid                        from com.withgratitude.api.core.dao.Bids b, com.withgratitude.api.core.dao.Users u                        where b.userId = u.userId                        order by CONCAT(u.firstName, ' ', u.lastName)]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.ErrorTracker.throwQueryException(ErrorTracker.java:93) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:296) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:188) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:143) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:119) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:595) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:704) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
... 83 common frames omitted
  

Ответ №1:

Здесь много проблем — одна из них — возвращаемый тип (список объектов ReportTopTenBiddersTable), который, по-видимому, не оставляет места для полной информации о ставке.

Части не подходят (есть sql, смешанный с jpql), типы не совпадают — но из этого короткого примера трудно сказать, что является источником ошибок — и лучшее решение.

Одним из самых простых решений было бы добавить информацию о ставке в объект ReportTopTenBiddersTable; таким образом, вы можете удалить case (но при этом сохранить данные) и сохранить подпись нетронутой:

  • измените конструктор ReportTopTenBiddersTable , чтобы он принимал объект «Bid» (и сохранял его в поле).

  • измените вызов конструктора в начале запроса на include b (вы можете не указывать дату, потому что она доступна в b любом случае):

   select new com.withgratitude.api.core.domain.ReportTopTenBiddersTable(
      CONCAT(u.firstName, ' ', u.lastName), b.auctionId, b.date) ... 
  

Ответ №2:

Чтобы добавить к ответу Andronicus, я думаю, вы можете использовать nativeQuery и записать свой запрос к базе данных в обычном SQL.

 @Query(value = "select CONCAT(u.first_name, ' ', u.last_name) as name, b.auction_id, b.date, "  
        "case b.is_thewinner when 0 then 'No' when 1 then 'Yes' end as WinnerBid, b.offer "  
        "from bids b, users u "  
        "where b.user_id = u.user_id "  
        "order by name "  
        "limit 10", nativeQuery = true)
List<ReportTopTenBiddersTable> reportTopTenBiddersTable();