Нельзя использовать resultSet.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE) с пружиной jdbc DaoSupport с Oracle

Я хочу использовать прокручиваемый набор результатов, поэтому, когда я использую две строки кода:

 rs.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE);
rs.absolute(12);

в моем DAOimpl, я получаю исключение, плз, помогите решить их, заранее спасибо.

 import oracle.jdbc.OracleTypes;
    import org.springframework.jdbc.core.CallableStatementCallback;
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    import org.springframework.stereotype.Component;
    @Component
    public class MyDAOimpl extends JdbcDaoSupport implements
            MyDAO {

        public List<User> getList(final String where) throws Exception {

            return (List) getJdbcTemplate().execute(
                    "{call PKG_USER.getUser(?,?)}",
                    new CallableStatementCallback() {
                        public Object doInCallableStatement(CallableStatement cs)
                                throws SQLException {

                            cs.setString(1, where);
                            cs.registerOutParameter(2, OracleTypes.CURSOR);
                            cs.execute();

                            ResultSet rs = (ResultSet) cs.getObject(6);

                            rs.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE);
                            rs.absolute(12);

                            List<User> list = new ArrayList<User>();

                            while (rs.next()) {

                                User user = new User(
                                        rs.getString(1),
                                        rs.getString(2), 
                                        rs.getString(3));
                                list.add(user);
                            }
                            return list;
                        }
                    });

        }
    }

это исключение

java.sql.SQLException: Invalid argument(s) in call: setFetchDirection
    oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
    oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
    oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
    oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:263)
    oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:271)
    oracle.jdbc.driver.BaseResultSet.setFetchDirection(BaseResultSet.java:128)

////////////////////////////////////////////////// ////////////////////////////////////////

где я меняю, как показано ниже, я не получил никакого результата, обычно моя процедура возвращает 100 пользователей:

return (List) getJdbcTemplate().execute(new CallableStatementCreator() {

            public CallableStatement createCallableStatement(
                    Connection connection) throws SQLException {
                return connection.prepareCall(
                        "{call PKG_USER.getUser(?,?)}",
                        ResultSet.TYPE_SCROLL_SENSITIVE,
                        ResultSet.TYPE_SCROLL_INSENSITIVE);
            }
        }, new CallableStatementCallback() {

            public Object doInCallableStatement(CallableStatement cs)
                    throws SQLException, DataAccessException {

                cs.setString(1, where);
                cs.registerOutParameter(2, OracleTypes.CURSOR);
                cs.execute();

                ResultSet rs = (ResultSet) cs.getObject(6);

                //////not run////
                rs.absolute(12);
                ////////////////

                List<User> list = new ArrayList<User>();

                while (rs.next()) 
                {   
                    List<User> list = new ArrayList<User>();

                            while (rs.next()) {

                                User user = new User(
                                        rs.getString(1),
                                        rs.getString(2), 
                                        rs.getString(3));
                                list.add(user);
                            }
                            return list;
            }
        });

2 ответа

Первый, ResultSet.TYPE_SCROLL_SENSITIVE является константой, указывающей тип набора результатов, и, конечно, не является допустимым аргументом для setFetchDirection который ожидает пятого направления. Цитирование раздела параметров Ja vadoc ResultSet#setFetchDirection(int direction):

direction - ан int указание предполагаемого направления выборки; один из ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, или же ResultSet.FETCH_UNKNOWN

Отсюда исключение и сообщение "Неверный аргумент (ы) в вызове: setFetchDirection ".

И кстати, согласно Oracle " Руководство и справочник разработчика JDBC " (все версии доступны по http://tahiti.oracle.com/) в разделе "Обработка прокручиваемого результирующего набора":

Предварительная настройка направления выборки

Стандарт JDBC 2.0 позволяет предварительно указывать направление, известное как направление выборки, для использования при обработке набора результатов. Это позволяет драйверу JDBC оптимизировать его обработку. Указаны следующие методы набора результатов:

  • void setFetchDirection(int direction) throws SQLException * int getFetchDirection() throws SQLException

Драйверы JDBC Oracle поддерживают только предустановленное значение вперед, которое можно указать, введя ResultSet.FETCH_FORWARD значение статической константы.

Ценности ResultSet.FETCH_REVERSE а также ResultSet.FETCH_UNKNOWN не поддерживаются Попытка указать их вызывает предупреждение SQL, а настройки игнорируются.

Это также упоминается в файле readme драйверов базы данных Oracle Database 11g Release 2 (окончательная версия на момент написания этой статьи):

Реализация прокручиваемого результирующего набора имеет следующее ограничение:

  • setFetchDirection () на Scrollable Result Set ничего не делает.

Но все это было неким побочным setFetchDiretion это просто не способ получить прокручиваемый набор результатов.

Чтобы создать прокручиваемый набор результатов с помощью Spring JdbcTemplate, вы должны использовать метод execute(CallableStatementCreator csc, CallableStatementCallback action) с обычаем CallableStatementCreator реализация. В этой реализации используется метод Connection.prepareCall(String sql, int resultSetType, int resultSetConcurrency) создать CallableStatement что будет производить ResultSet объекты с заданным типом и параллелизмом. Наконец, позвоните rs.absolute(),


ОБНОВЛЕНИЕ: есть проблема в connection.prepareCall() вызов, третий параметр должен быть типом параллелизма (либо ResultSet.CONCUR_READ_ONLY или же ResultSet.CONCUR_UPDATABLE). Попробуй это:

            return connection.prepareCall(
                    "{call PKG_USER.getUser(?,?)}",
                    ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_UPDATABLE);

Чтобы получить пользовательский набор результатов из шаблона jdbc. Spring предоставила PreparedStatementCreatorFactory, из которого вы можете создать PreparedStatementCreator.

      PreparedStatementCreatorFactory pc = new PreparedStatementCreatorFactory(sqlQuery, , new int[] {Types.VARCHAR});//query and params Types
pc.setResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);//TYPE_SCROLL_INSENSITIVE 
pc.setUpdatableResults(false);//CONCUR_READ_ONLY

jdbcTemplate.query(pc.newPreparedStatementCreator(listOfParams),
                        myResultSetExtractor);//perform query with custom psc, process results at ResultSetExtractor
Другие вопросы по тегам