迁移到 Hibernate 6 后查询中断

问题描述 投票:0回答:1

当更新到 Hibernate 6(来自 5.6)时,一些现有的查询被破坏了。

例如,执行此查询在 5.6 中运行良好:

  @Query(
      "SELECT new Position(p, CASE WHEN p.sourceSetId IS NULL THEN p.sourceSetName ELSE s.name END as sourceSetName, pos.optimizedDisplayOrder) FROM Position p "
          + "LEFT JOIN Position pos ON pos.projectId = p.projectId AND pos.positionId = p.sourceSetPositionId "
          + "LEFT JOIN Manufacturer m ON p.optimizedItem.manufacturer.manufacturerId = m.manufacturerId "
          + "LEFT JOIN Set s ON p.sourceSetId = s.setId AND p.projectId = s.projectId "
          + "WHERE p.setId = :setId AND p.projectId = :projectId "
          + "AND (UPPER(p.optimizedItem.code) LIKE UPPER(CONCAT('%', :searchParam, '%')) "
          + "OR UPPER(m.name) LIKE UPPER(CONCAT('%', :searchParam, '%')) "
          + "OR UPPER(p.optimizedItem.description) LIKE UPPER(CONCAT('%', :searchParam, '%')))")

但是在 6 中导致以下错误:

2023-05-16T16:35:37.867+02:00  WARN 21803 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 42P01
2023-05-16T16:35:37.867+02:00 ERROR 21803 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: missing FROM-clause entry for table "o1_0"
  Position: 743
2023-05-16T16:35:37.875+02:00 ERROR 21803 --- [nio-8080-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.InvalidDataAccessResourceUsageException: JDBC exception executing SQL [select p1_0.position_id,p1_0.comment,p1_0.create_date,p1_0.last_modified_by,p1_0.last_modified_date,p1_0.optimized_display_order,case when p1_0.optimized_item_id IS NULL then p1_0.original_item_id else p1_0.optimized_item_id end ,p1_0.optimized_item_id,p1_0.optimized_quantity,p1_0.original_display_order,p1_0.original_item_id,p1_0.original_quantity,p1_0.project_id,p1_0.set_id,p1_0.source_set_id,p1_0.source_set_name,p1_0.source_set_position_id,case when p1_0.source_set_id is null then p1_0.source_set_name else s1_0.name end,p2_0.optimized_display_order from nemo_dev.position p1_0 left join nemo_dev.position p2_0 on p2_0.project_id=p1_0.project_id and p2_0.position_id=p1_0.source_set_position_id left join nemo_dev.manufacturer m1_0 on o1_0.manufacturer_id=m1_0.manufacturer_id left join nemo_dev.set s1_0 on p1_0.source_set_id=s1_0.set_id and p1_0.project_id=s1_0.project_id join nemo_dev.item o1_0 on o1_0.item_id=case when p1_0.optimized_item_id IS NULL then p1_0.original_item_id else p1_0.optimized_item_id end  where p1_0.set_id=? and p1_0.project_id=? and (upper(o1_0.code) like upper(('%'||?||'%')) escape '' or upper(m1_0.name) like upper(('%'||?||'%')) escape '' or upper(o1_0.description) like upper(('%'||?||'%')) escape '') order by p1_0.optimized_display_order asc offset ? rows fetch first ? rows only]; SQL [n/a]] with root cause

org.postgresql.util.PSQLException: ERROR: missing FROM-clause entry for table "o1_0"
  Position: 743
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2676) ~[postgresql-42.5.4.jar:42.5.4]
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2366) ~[postgresql-42.5.4.jar:42.5.4]
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:356) ~[postgresql-42.5.4.jar:42.5.4]
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:496) ~[postgresql-42.5.4.jar:42.5.4]

我已经阅读了迁移指南但找不到对此的解释。

我错过了什么吗?

java hibernate spring-data-jpa hibernate-6.x
1个回答
0
投票

据我从查询中了解到,您返回的 DTO 与您查询的实体同名。所以你需要以某种方式区分它们。请使用 DTO 声明的完全限定名称:

@Query(
      "SELECT new com.your.package.name.Position(p, CASE WHEN p.sourceSetId IS NULL THEN p.sourceSetName ELSE s.name END as sourceSetName, pos.optimizedDisplayOrder) FROM Position p "
          + "LEFT JOIN Position pos ON pos.projectId = p.projectId AND pos.positionId = p.sourceSetPositionId "
          + "LEFT JOIN Manufacturer m ON p.optimizedItem.manufacturer.manufacturerId = m.manufacturerId "
          + "LEFT JOIN Set s ON p.sourceSetId = s.setId AND p.projectId = s.projectId "
          + "WHERE p.setId = :setId AND p.projectId = :projectId "
          + "AND (UPPER(p.optimizedItem.code) LIKE UPPER(CONCAT('%', :searchParam, '%')) "
          + "OR UPPER(m.name) LIKE UPPER(CONCAT('%', :searchParam, '%')) "
          + "OR UPPER(p.optimizedItem.description) LIKE UPPER(CONCAT('%', :searchParam, '%')))")
© www.soinside.com 2019 - 2024. All rights reserved.