Изменение режима ResultSetType в Hibernate / JPA - PullRequest
1 голос
/ 04 июля 2019

У меня следующая проблема:

Это моя реализация репозитория для данного

public class SearchRepoImpl<T, ID extends Serializable>  implements SearchRepo<T,ID> {

    private final EntityManager em;

    @Override
    public Stream<T> findStreamBySpec(Specification<T> where, Integer limit, Class<T> clazz) {
        final Class<T> domainClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<T> query = builder.createQuery(domainClass);


        applySpecificationToCriteria(where, domainClass, query); // this method does the necessary preprocessing and is of no interest
        return em.createQuery(query)
                .getResultStream()
                .limit(limit.longValue());
    }
}

Однако, когда я вызываю эту реализацию, используя searchRepo.findStreamBySpec(spec, 100, MyClass.class).forEach(e-> {...}), я получаю следующее исключение:

org.hibernate.exception.GenericJDBCException: Не удалось определить, набор результатов пуст из-за вызова исключения isBeforeFirst или isAfterLast ()

Мне удалось отследить проблему до декомпилированной строки кода в драйвере DB2:

private final void checkThatResultSetTypeIsScrollable() throws SQLException {
   if (this.resultSetType_ == ResultSet.FORWARD_ONLY) {
      throw hd.a(this, this.agent_.logWriter_, ErrorKey.METHOD_NOT_ALLOWED_ON_FORWARD_ONLY_CURSOR, "10900");
   }
}

Этот метод, в свою очередь, вызывается из HikariProxyResultSet

    public boolean isBeforeFirst() throws SQLException {
        this.agent_.systemMonitor_.c();

        boolean var2;
        try {
            if (this.agent_.loggingEnabled()) {
                this.agent_.logWriter_.traceEntry(this, "isBeforeFirst");
            }

            this.checkForClosedResultSet();
            this.checkThatResultSetTypeIsScrollable();
          //^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ calls above method checkThatResultSetTypeIsScrollable()
            boolean var1 = this.isBeforeFirstX();
            if (this.agent_.loggingEnabled()) {
                this.agent_.logWriter_.traceExit(this, "isBeforeFirst", var1);
            }

            var2 = var1;
        } finally {
            this.agent_.systemMonitor_.a(this.statement_);
        }

        return var2;
    }

который был вызван с

    private boolean isResultSetEmpty() {
        try {
            return currentPosition == 0 && !getResultSet().isBeforeFirst() && 
!getResultSet().isAfterLast();
                                         //^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ calls above method  isBeforeFirst()           
        }
        catch (SQLException e) {
            throw getSession().getFactory().getSQLExceptionHelper().convert(
                    e,
                    "Could not determine if resultset is empty due to exception calling isBeforeFirst or isAfterLast()"
            );
        }
    }

У меня вопрос, есть ли способ намека или подсказки Hibernate, HikariCP и / или DB2, которые я не хочу устанавливать ResultSet на FORWARD_ONLY или что я не хочу использовать такого рода прокручиваемого результата.

...