На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Следующие правила действуют в данном разделе в дополнение к общим Правилам Форума
1. Здесь обсуждается Java, а не JavaScript! Огромная просьба, по вопросам, связанным с JavaScript, SSI и им подобным обращаться в раздел WWW Masters или, на крайний случай, в Многошум.
2. В случае, если у вас возникают сомнения, в каком разделе следует задать свой вопрос, помещайте его в корневую ветку форума Java. В случае необходимости, он будет перемещен модераторами (с сохранением ссылки в корневом разделе).

3. Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.
4. Не рекомендуется создавать несколько несвязанных вопросов в одной теме. Пожалуйста, создавайте по одной теме на вопрос.
Модераторы: dark_barker, wind
  
> Как создать копию объекта?
    проблема в следующем.
    Есть некая функция
    public ResultSet fun(){
    ResultSet rs = statement.executeQuery(sql);
    ResultSet rs2 = rs;
    rs.close();
    return rs2;
    }
    После вызова данной функции java выдаст ошибку мол ресалт сет зокрыт, потому что объек rs2 ссылается на объект созданный rs (так называемая дублирующая сылка )
    Как мне создать копию объекта rs и передать ее в rs2? Метод clone() не доступен.
      Используй метод clone() :)

      т.е. Создай свой класс унаследованный от ResultSet только добавиш implements Cloneable. Почитай про этот интерфейс, есть много примеров по созданию копии объекта.
      Сообщение отредактировано: Alien -
        Цитата
        Используй метод clone()

        Я бы рад, но ...
        Может кто нибудь еще потскадет?
          В своем РезалСете допиши метод clone()
          ExpandedWrap disabled
            public Object clone() {
                //shallow copy
                try {
                  return super.clone();
                } catch (CloneNotSupportedException e) {
                  return null;
                }
              }

          Таким образом ты получишь не ссылку на объект, а его копию. :)
            [/QUOTE]т.е. Создай свой класс унаследованный от ResultSet только добавиш implements Cloneable. Почитай про этот интерфейс, есть много примеров по созданию копии объекта.
            [QUOTE]
            Я уже пытался так сделать и вот что мне говорит eclipse "The type ResultSet cannot be the superclass of MyResultSet; a superclass must be a class"
            Я выяснил что ResultSet это интерфейс а не класс и еще больше зашел в тупик.
            Нужна компетентная помощь
              ResultSet - это, действительно, интерфейс. Релизацию для него предоставляет конкретный драйвер, и влезать в него не больно-то хорошо.

              marlborist, а вчем, собственно, состоит задача? Если более общо смотреть. Может, можно обойтись и без клонирования?
                А что мешает хранить копию данных, которые содержит этот интерфейс?
                Сообщение отредактировано: Alien -
                  Привет Alien.
                  Цитата

                  marlborist, а вчем, собственно, состоит задача? Если более общо смотреть. Может, можно обойтись и без клонирования?

                  Вот что конкретно делает моя функция:
                  1) имя функции: public ResultSet executeStoredProcedure(Param1 param1, Param2 param2, ...){...}
                  2)В ней создается хранимая процедура c именем "proc" которой передаются параметры из функции
                  3)Затем процедура с именем proc экзекьютится: proc.execute().
                  4)Затем берется его ResultSet . ResultSet rs = proc.getResultSet(); то есть rs это ссылка.
                  5)Закрывается процедура proc.close();
                  6)Возвращается rs.

                  так вот этот rs который является ссылкой после закрытия процедуры тоже закрывается.
                  Как я понял если после шага 4 создать копию объекта
                  а не ссылку на объект то можно смело закрывать процедуру.

                  Толька как мне это зделать? А может есть другой выход?
                    marlborist, мне кажется, что ваш подход изначально неверен. Использование ссылок на фукнции - достаточно мощный инструмент в C++, но в Java можно найти другой путь.

                    Мне немного непонятно ваше объяснение. Что значит proc.execute()? Если proc - это Method, то там нет такого метода ;)
                    Может proc - объект PreparedStatement?

                    Опишите подробнее зачем вообще нужна executeStoredProcedure()
                      Цитата

                      Опишите подробнее зачем вообще нужна executeStoredProcedure()

                      public Object executeStoredProcedure(String proc_name, ArrayList params,ArrayList modifics, boolean has_return_value) {
                      Object return_value = null;
                      String body = "";
                      // Count how many parameters procedure body have.
                      for (Iterator it = params.iterator(); it.hasNext(); it.next()) {
                      body += "?,";
                      }

                      if(!params.isEmpty()) {
                      body=body.substring(0, body.length()-1);
                      }

                      try {
                      String sql_statement = ((has_return_value) ? "{?=" : "{") + "call "+ proc_name + "(" + body + ")}";
                      proc = connection.prepareCall(sql_statement);
                      int sqlType;
                      Object curr_param;
                      Object curr_modific;
                      int j = 1;

                      // If procedure have return value?, ther return value must register.
                      if (has_return_value) {
                      proc.registerOutParameter(j++, Types.INTEGER);
                      }
                      Iterator iter = modifics.iterator();
                      sqlType = Types.OTHER;

                      for (Iterator it = params.iterator(); it.hasNext(); ++j) {
                      curr_param = it.next();
                      curr_modific = iter.next();
                      proc.setObject(j, curr_param);

                      // Check if output param.
                      if (((Integer) curr_modific).intValue() == OUT) {
                      proc.registerOutParameter(j, sqlType);
                      }
                      }

                      // Execute stored procedure on server.
                      proc.execute();
                      // Parsing output params.
                      j = ((has_return_value) ? 2 : 1);
                      int i = 0;

                      // Set return value.
                      if (has_return_value) {
                      return_value = proc.getObject(1);
                      } else {
                      return_value=proc.getResultSet();
                      }
                      ResultSet rs ;
                      // Output parameters in ArrayList params must be replaced by
                      // modified value after stored procedure executed.
                      for (iter = modifics.iterator();(has_return_value) ? j <= params.size() + 1 : j <= params.size();j++, i++) {
                      curr_modific = iter.next();

                      if (((Integer)curr_modific).intValue() == OUT) {
                      curr_param = proc.getObject(j);
                      params.set(i, curr_param);
                      }
                      }
                      } catch (Exception e) {
                      e.printStackTrace();
                      }
                      return return_value;
                      }

                      ----------------------------------------------------
                      Вот она сама канкретная функция. Как вы можете заметить я не вызывал метод close() для объекта proc, то есть proc.close().

                      Есть ли какая то возможность закрыть хранимую процедуру при этом не потеряв данные, а именно ResaltSet?
                      Все еще жду решения своей проблемы! :wall:
                        Прошу прощения: с утра пораньше неправильно понял что значит "хранимая процедура" :D

                        В вашем случае я бы поступил следующим образом (хотя конечно это ИМХО, возможно кто-то предложит вариант получше :) ):
                        - если размер возвращаемых данных невелик - кидаем все в коллекцию и возвращаем ее
                        - если размер данных достаточно большой, то используем слушателей

                        Поясню: если я правильно понял, то executeStoredProcedure() - универсальный "запускатель" SQL-процедур. В таком случае создаем какой-нибудь интерфейс типа StoredProcedureCallingListener, в котором объявляем метод procedureExecuted(String procedureName, ResultSet rs), который и будет заниматься обработкой данных.

                        В классе, где лежит executeStoredProcedure() добавляем публичные методы addStoredProcedureCallingListener(StoredProcedureCallingListener listener) (регистрация слушателя) и removeStoredProcedureCallingListener(StoredProcedureCallingListener listener) (снятие с учета :)). Соотвественно этих слушателей где-то нужно хранить.

                        При вызове executeStoredProcedure() нужно вызвать у всех зарегистрированных слушателей метод procedureExecuted(String procedureName, ResultSet rs) с соответствующим параметром. После вызова благополучно все закрываем.

                        Ну а регистрировать слушателя нужно для каждой используемой хранимой процедуры.

                        Хотелось бы еще отметить:

                        Цитата
                        String body = "";
                        // Count how many parameters procedure body have.
                        for (Iterator it = params.iterator(); it.hasNext(); it.next()) {
                        body += "?,";
                        }


                        Во-первых, в комментариях подправить на has :)
                        Во-вторых, использовать не String, а StringBuilder, т.к. String - немутабельный объект.
                          На счет коллекций: если я не найду другого выхода то придется использовать этот как запасной вариант.
                          На счет добавления слушателей: тоже можно использовать как запасной вариант, во первых я не очень понял что вы имели ввиду, но я понял что в коде где вызывался метод executeStoredProcedure() нужно делать допалнительные приседания вызывая различные методы, это тоже проблемно ковыряться во всем проекте(а он не малеький) и искать где вызывался метод executeStoredProcedure (). Мне на много будет легче если я как нибудь передам копию объекта
                          а процедуру закрою. Тогда мне ни чего не придется изменять, в классах где я вызывал этот метод.
                          1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0,0354 ]   [ 14 queries used ]   [ Generated: 20.05.24, 04:39 GMT ]