【问题标题】:Hibernate generating query for Oracle which causes ORA-02014Hibernate 为 Oracle 生成查询,导致 ORA-02014
【发布时间】:2016-05-03 05:55:53
【问题描述】:

我的项目使用 Hibernate 版本 4.0.1.Final 和 JPA 2.0。我需要更改一个 HQL - 添加顺序,看起来很简单,只是它现在以 SQL 语法错误结尾。

我已经定义了这个 HQL 命名查询:

SELECT s FROM Entity s WHERE s.status = :status ORDER BY s.priority, s.startDate

-> 粗体是我要添加的部分。

现在,由于这个命名查询是使用锁执行的 - LockModeType.PESSIMISTIC_WRITE 它为 Oracle 的更新选择创建:

select *
  from (select entity.field 

  ...more fields...

          from DB_TABLE entity
         where (entity.STATUS = ?)
         order by entity.PRIORITY, entity.DISTRIB_START_DATE)
 where rownum <= ?
   for update

这个查询以

结尾

java.sql.SQLSyntaxErrorException: ORA-02014 无法从具有 DISTINCT、GROUP BY 的视图中选择 FOR UPDATE

没有订单部分它工作正常。

有什么办法可以解决这个问题吗?我只需要按顺序选择这些记录。也不能在应用程序中订购它们,因为它只选择表的一部分。

我尝试将 Hibernate 更新到 4.2.21.Final 但结果是一样的。 Hibernate 4.3+ 需要我不使用的 JPA2.1。
也许这是 Hibernate 的错误?

【问题讨论】:

    标签: java oracle hibernate jpa


    【解决方案1】:

    不,这不是 Hibernate 错误,它是您在 Oracle 中结合rownum 进行排序的方式。详情请见this article

    基本上,这意味着您不能在 Oracle 的同一查询中组合排序、rownumselect for update

    您必须将其分解为更多查询,具体方法取决于您的具体要求。例如:

    1) 选择具有 pagingordering 的实体的 id:

    SELECT s.id FROM Entity s WHERE s.status = :status ORDER BY s.priority, s.startDate
    

    2) 使用获得的 id 选择具有 locking 的实体:

    SELECT s FROM Entity s WHERE s.id in :ids AND s.status = :status
    

    3) 如果选择的实体的数量小于id的数量,那么同时条件已经改变(状态已经改变),继续处理锁定的实例或回滚并重试整个事务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多