tl; dr Как написать следующий запрос: SELECT * FROM T_BATCH_DATA WHERE ID IN (SELECT ID FROM T_BATCH_DATA OFFSET 5 ROWS FETCH FIRST 10 ROWS ONLY) FOR UPDATE ;
с использованием JPQL ?
У меня запрос с именем JPQL: name=Foo.foo, query = "FROM Foo foo WHERE foo.modified<:date"
, который должен извлекать постраничные результаты и устанавливать блокировку для предотвращения одновременного чтения другим POD.Ниже приведен соответствующий код:
findFooByLastInteractionUpdate(int pageIndex, int noOfRecords, LocalDateTime retentionDate)
{
return entityManager.createNamedQuery("Foo.foo", Foo.class)
.setParameter("date", date) //
.setFirstResult(pageIndex * noOfRecords) //
.setMaxResults(noOfRecords) //
.setLockMode(LockModeType.PESSIMISTIC_WRITE) //
.getResultList();
}
Модульный тест очень прост и выглядит так:
// given:
initializeDb();
LocalDateTime date = ...;
// when:
List<Foo> result = cut.findFooByLastInteractionUpdate(0, 3, date);
// then:
Assert.assertEquals(2, result.size());
А метод инициализации выглядит так:
initializeDb() {
getEntityManager().createNativeQuery("INSERT INTO FOO (ID, ..., ..., ...) VALUES (1, ..., ..., ...)").executeUpdate();
}
Однако, когда я выполняю этот запрос, получаются следующие журналы: javax.persistence.PessimisticLockException: Exception [EclipseLink-4002 (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.h2.jdbc.JdbcSQLException:
Syntax error in SQL statement ... FROM FOO WHERE (MODIFIED < ?) FOR UPDATE LIMIT[*] ? OFFSET ? ";
SQL statement: SELECT FOO ... FROM FOO WHERE (MODIFIED < ?) FOR UPDATE LIMIT ? OFFSET ? [42000-196]
Error Code: 42000
В руководстве по H2 я обнаружил, что код 42000 соответствует синтаксической ошибке.Имея доступ только к базе данных Oracle, я попытался выполнить подобный запрос вручную, поэтому:
SELECT * FROM FOO FOR UPDATE FETCH FIRST 10 ROWS ONLY OFFSET 5 ROWS;
, что приводит к ORA-02014
.
Однако мне удалось переписатьзапрос выполняется успешно:
SELECT * FROM T_BATCH_DATA WHERE ID IN (SELECT ID FROM T_BATCH_DATA OFFSET 5 ROWS FETCH FIRST 10 ROWS ONLY) FOR UPDATE ;
Как переписать запрос JPQL?