0

我正在开发一个使用 oracle 数据库的应用程序。要连接数据库,我正在使用 Hibernate。我是 Hibernate 的新手,遇到了一个问题,所以需要一些帮助。我的情况是:

  1. 从数据库中选择一些处理状态(我表中的一列)为“N”的行</li>
  2. 将这些行的 ProcessingStatus 更新为“U”</li>
  3. 对数据应用一些逻辑
  4. 将 ProcessingStatus 更改为“Y”</li>

我编写了一个代码,如果我将它作为单个进程运行它会很好,但是如果我运行同一个应用程序的多个实例,就会出现问题,不同的进程可能会选择相同的行来处理我不想要的。所以我想锁定选择行返回的所有行,将它们的 ProcessingStatus 更新为“U”,然后释放锁定。为此,我在 Criteria 中获得了一个 API criteria.setLockMode(LockMode.UPGRADE),我计划在运行选择查询时使用它,这样任何其他行都不会选择这些行,但问题是当我使用此 API 时出现错误错误是:

2602 [main] WARN org.hibernate.util.JDBCExceptionReporter  - SQL Error: -11, SQLState: 37000
2602 [main] WARN org.hibernate.util.JDBCExceptionReporter  - SQL Error: -11, SQLState: 37000
2603 [main] ERROR org.hibernate.util.JDBCExceptionReporter  - Unexpected token: FOR in statement [select this_.CUSTOMER_ID as CUSTOMER1_2_0_, this_.MARKETPLACE_ID as MARKETPL2_2_0_, this_.PROCESSING_DATE as PROCESSING3_2_0_, this_.AMOUNT as AMOUNT2_0_, this_.LAST_SHIP_DATE as LAST5_2_0_, this_.ORDER_DATE as ORDER6_2_0_, this_.PROCESSING_STATUS as PROCESSING7_2_0_, this_.PURCHASE_ID as PURCHASE8_2_0_, this_.QUANTITY as QUANTITY2_0_ from CUSTOMERS_FIRST_ORDER this_ where this_.PROCESSING_DATE=? and this_.MARKETPLACE_ID=? and this_.PROCESSING_STATUS=? limit ? for update]

有人可以帮我解决这个问题。我没有得到我做错了什么。如果我使用LockMode.READ它,那么它可以工作,但它会在升级/写入模式下出错。

引发错误的代码是:

@SuppressWarnings("unchecked")
@Transactional
public List<CustomerFirstOrder> getOrders(final Date processingDate, long marketplaceID, int count) throws Exception {
    final Session session = getSession();
    final Criteria criteria = session.createCriteria(CustomerFirstOrder.class);
    criteria.add(Restrictions.eq(PROCESSING_DATE, processingDate));
    criteria.add(Restrictions.eq(MARKETPLACE_ID, marketplaceID));
    criteria.add(Restrictions.eq(PROCESSING_STATUS, ProcessingStatus.NOTPROCESSED.toString().charAt(0)));                ///Select only unprocessed rows
    criteria.setMaxResults(count); // select multiple rows
    criteria.setLockMode(LockMode.UPGRADE);
    LOGGER.debug("selecting multple row for date " + processingDate + " of marketplace " + marketplaceID + " of status " + ProcessingStatus.NOTPROCESSED);
    final List<CustomerFirstOrder> results;
    try {
            results = (List<CustomerFirstOrder>)criteria.list();
            return results;
        }
    }
}
4

2 回答 2

0

Oracle 不支持子句,因此如果 Hibernate配置为使用 Oracle 方言,则它limit无法生成带有子句的查询。limit

因此,您需要配置 Hibernate以使用正确的 Oracle 方言来使 Hibernate 为 Oracle 生成正确的查询。

于 2012-04-13T11:40:26.670 回答
0

通过 Hibernate 在 Oracle 中使用限制和 for update 子句存在已知问题,至少可以追溯到几年前。请参阅此错误报告。尝试取出以下行:

criteria.setMaxResults(count);

并再次运行测试。作为旁注,LockMode.UPGRADE在 Hibernate 中已弃用,您应该PESSIMISTIC_WRITE改用它。

于 2012-04-13T11:15:01.733 回答