Hibernate生成Oracle的查询,导致ORA-02014

时间:2016-01-26 15:39:26

标签: java oracle hibernate jpa

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

我已经定义了这个名为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的错误?

1 个答案:

答案 0 :(得分:3)

不,它不是Hibernate的错误,它是您在Oracle中与rownum结合使用的方式。有关详细信息,请参阅this article

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

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

1)选择分页排序的实体ID:

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

2)使用获取的ID选择锁定的实体:

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

3)如果所选实体的计数小于id的数量,则同时条件已更改(状态已更改),使用锁定的实例继续处理或回滚并重试整个事务。