在Domino对象上使用recycle会导致bean不返回数据

时间:2013-03-22 10:45:42

标签: java javabeans xpages

我有一个会话范围的bean,它读取视图的内容并存储SelectItem对象的hashmap。然后使用它们来填充XPage上的组合框值。

当我尝试在最里面的循环中回收ViewEntry对象时,代码工作正常除外。如果该行被注释掉,我的SelectItems返回正常。如果该行未被注释,我的组合框是空的。所以我想知道的是:

  1. 为什么会这样?
  2. 如何解决这个问题,并像正常的开发人员那样正确地回收对象?
  3. 如果我无法明确回收该对象,那么对内存的潜在影响是什么?
  4. 代码(突出显示问题行并且当前已注释掉):

    public class comboBox extends HashMap<String, List<SelectItem>> implements Serializable {
        private static final long serialVersionUID = 1L;
        public comboBox() {
            this.init();
        }
    
        private void init() {
            Database database = null;
            View vwData = null;
            ViewNavigator navData = null;
            try {
                PrimeUser thisUser = (PrimeUser) resolveVariable(FacesContext.getCurrentInstance(), "PrimeUser");
                String lang = thisUser.getLang();
                database = getCurrentDatabase();
                vwData = database.getView("DataLookup");
                navData = vwData.createViewNavFromCategory(lang);
                ViewEntry keyCat = navData.getFirst();
                ViewEntry nextCat = null;
                while (keyCat != null) {
                    String thisKey = (String) keyCat.getColumnValues().get(1);
                    List<SelectItem> options = new ArrayList<SelectItem>();
                    options.add(new SelectItem("Please select..."));
                    ViewEntry dataEntry = navData.getChild(keyCat);
                    ViewEntry nextChild = null;
                    while (dataEntry != null) {
                        nextChild = navData.getNextSibling();
                        Object optValue = dataEntry.getColumnValues().get(2);
                        String optLabel = (String) dataEntry.getColumnValues().get(3);
                        options.add(new SelectItem(optValue, optLabel));
    
                        // dataEntry.recycle(); //<---- PROBLEM HERE
    
                        dataEntry = nextChild;
                    }
                    this.put(thisKey, options);
                    nextCat = navData.getNextCategory();
                    keyCat.recycle();
                    keyCat = nextCat;
                }
            } catch (NotesException e) {
                e.printStackTrace();
            } finally {
                try {
                    navData.recycle();
                    vwData.recycle();
                    database.recycle();
                } catch (NotesException e) {
                }
            }
        }
    
        public List<SelectItem> get(String key) {
            return this.get(key);
        }
    }
    

    解决:

    分辨率非常简单(感谢Sven Hasselbach提醒我再次查看服务器日志输出)。变化很简单 - 交换这一行:

                nextCat = navData.getNextCategory();
    

    为此:

                nextCat = getNextSibling(keyCat);
    

    虽然&#34; getNextCategory&#34;是ViewNavigator的一种方法,没有任何参数;它只获得当前条目后的下一个类别。如果当前条目已被回收 - 如上所述 - 那么显然当前条目为null并且该方法抛出异常。

    &#34; getNextSibling&#34;有一个可选的ViewEntry参数,如果指定,它将覆盖指向当前ViewEntry的指针,否则它将使用它。

    我责怪星期五。

1 个答案:

答案 0 :(得分:1)

首先看看你的服务器控制台:你在那里看到了一个N​​otesException吗?如果您遇到异常,您的 put 将永远不会执行,因此您的组合框将为空。

在回收对象之前,您必须测试它是否为 null ,由try / catch块包围。有一些实现可以更容易地回收Notes对象,例如:这一个http://openntf.org/XSnippets.nsf/snippet.xsp?id=recycleobject-helper-for-recycling-of-objects

有关回收的详细解释,请访问:http://nathantfreeman.wordpress.com/2013/03/21/recycle-and-the-retail-experience/