2 Replies Latest reply on Mar 21, 2012 12:23 PM by John Stegeman

    Multiple calls to execute() on an OperationBinding fail after first call

    884628
      (I am using jDeveloper v11.1.1.5.0.)

      I have a method in a ViewObjectImpl class that does a simple "findByKey", using a string that is passed to the method as the key, and returns the found row. I have the method bound to a page, and in a backing bean, I am trying to call the method. I get a handle to the OperationBinding for the method, get the ParameterMap object, and add (put) a parameter of the string I want to pass to the method. I then call execute() on the OperationBinding and get back the Row (if found).

      This all works the first time.

      The problem is that in my bean, I am actually doing this iteratively. The first time, everything works. The second time I call execute(), it appears that the parameter map is not getting passed to the method, as all of the parameters are 'null' from within the method.

      Below is the code for the method in the ViewObjectImpl class for my view object:
          public Boolean isCommonWord(String word) {
              System.out.println("Checking word: " + word);
              if (word == null) return false; // short-circuit for null values
              Object[] keys = new Object[1];
              keys[0] = word.toUpperCase();
              Row[] rows = this.findByKey(new Key(keys), 1);
              System.out.println("Found " + rows.length + " matching words.");
              if (rows.length > 0) System.out.println("Word row 1: " + ((CommonWordsLOVRowImpl)rows[0]).getWord());
              return (rows.length == 1);
          }
      As you can see, "word" is the single parameter to the method. I dump the value to the console for debug, then (if not null) use it to create a Key object to use in findByKey, then return the row, if found.

      Here's the relevant code from my bean:
                      OperationBinding isCommonWord = ADFUtils.findOperation("isCommonWord");
                      params = isCommonWord.getParamsMap();
                      // Loop through all words in the string 'searchStr'
                      StringTokenizer st = new StringTokenizer(searchStr);
                      Collection<String> wordList = new HashSet<String>();
                      while (st.hasMoreTokens()) {
                          String s = st.nextToken();
                          _logger.finest(this.getClass().getName(), "findUserAndPlan","Checking word: " + s);
                          // Look up word
                          params.put("word", s);
                          _logger.finest(this.getClass().getName(), "findUserAndPlan","Parameters: " + params.toString());                    
                          if (!(Boolean)isCommonWord.execute()) {
                              // nope - add to collection
                              _logger.finest(this.getClass().getName(), "findUserAndPlan","Word OK");
                              boolean add = wordList.add(s);
                          }
                      }
      If 'searchStr' is "delta 36 inc", my output on the console is this:
      <CreateAccountBean> <findUserAndPlan> Checking word: delta
      <CreateAccountBean> <findUserAndPlan> Parameters: {word=delta}
      Checking word: delta
      Found 0 matching words.
      <CreateAccountBean> <findUserAndPlan> Word OK
      
      <CreateAccountBean> <findUserAndPlan> Checking word: 36
      <CreateAccountBean> <findUserAndPlan> Parameters: {word=36}
      Checking word: null
      <CreateAccountBean> <findUserAndPlan> Word OK
      
      <CreateAccountBean> <findUserAndPlan> Checking word: inc
      <CreateAccountBean> <findUserAndPlan> Parameters: {word=inc}
      Checking word: null
      <CreateAccountBean> <findUserAndPlan> Word OK
      As you can see, it calls the method three times, once for each word. In all three calls, you can see that the Parameters Map has one item in the map called "word", and it is set to the actual word from the searchStr (e.g. "delta", then "36", then "inc"). However the very next line is the output from within the method itself. The first time, the method shows it got the word ("Checking word: delta"), but in calls 2 and 3, the value it receives for 'word' is null! This is the problem.

      I'm sure I'm doing something wrong, but don't know what that is! :-) Thanks in advance for any suggestions.

      Edited by: Karl C on Mar 21, 2012 5:04 AM
        • 1. Re: Multiple calls to execute() on an OperationBinding fail after first call
          884628
          So, after sleeping on it, and having a clear(er) head this morning, I tried a few things. I was obviously setting my value in the "params" map, but it was not getting through to the method after the first call. So, I theorized that perhaps I couldn't reuse the "params" map on each call, and that the framework generated a new parameter map for each call.

          To test, I moved the one line of code where I get a handle to the parameter map to be inside the loop, as follows:
                          OperationBinding isCommonWord = ADFUtils.findOperation("isCommonWord");
                          // Loop through all words in 'searchStr'
                          StringTokenizer st = new StringTokenizer(searchStr);
                          Collection<String> wordList = new HashSet<String>();
                          while (st.hasMoreTokens()) {
                              String s = st.nextToken();
                              _logger.finest(this.getClass().getName(), "findUserAndPlan","Checking word: " + s);
                              // Look up word
                              params = isCommonWord.getParamsMap(); // <<=== This is the line I moved
                              params.put("word", s);
                              _logger.finest(this.getClass().getName(), "findUserAndPlan","Parameters: " + params.toString());                    
                              if (!(Boolean)isCommonWord.execute()) {
                                  // nope - add to collection
                                  _logger.finest(this.getClass().getName(), "findUserAndPlan","Word OK");
                                  boolean add = wordList.add(s);
                              }
                          }
          Guess what? It worked!

          So, I solved my own problem. I hope that this post perhaps can save someone else from beating their head against a wall for hours wondering why things aren't working! :-)
          • 2. Re: Multiple calls to execute() on an OperationBinding fail after first call
            John Stegeman
            I was just putting together a test case to test this - you beat me to it :)

            FYI: params.clear() doesn't work either - you do need to re-fetch the map each time it seems

            John
            1 person found this helpful