2013-03-22 53 views
0

我有一个会话scoped bean,它读取视图的内容并存储SelectItem对象的散列表。这些被用来在XPage上填充组合框值。在Domino对象上使用回收会导致Bean不返回数据

代码工作正常,除非我尝试回收最内层循环中的ViewEntry对象。如果该行被注释掉,我的SelectItems返回正常。如果该行没有注释,我的组合框就是空的。所以我想知道的是:

  1. 为什么会发生这种情况?
  2. 我该如何解决这个问题并像一个好的开发人员那样正确地回收对象?
  3. 如果我不能明确地回收对象,对内存等的潜在影响是什么?

代码(有问题的行强调,目前注释掉):

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); 
    } 
} 

解决:

该决议是烦人简单的(感谢斯文哈塞尔巴赫提醒我查看服务器日志再次输出)。这种变化是简单 - 交换这一行:

  nextCat = navData.getNextCategory(); 

此:

  nextCat = getNextSibling(keyCat); 

虽然“getNextCategory”是的ViewNavigator的方法,并没有任何参数;它仅在当前条目之后获得下一个类别。如果当前条目已被回收 - 就像上面的情况一样 - 那么显然当前条目为空,并且该方法抛出异常。

“getNextSibling”具有一个可选的ViewEntry参数,如果指定了该参数,它将覆盖指向当前ViewEntry的指针,否则它将使用该参数。

我责怪周五。

+0

Domino对象不能被序列化。因此,不能保证代码将按预期工作,并将其放入sessionScope中。 – 2013-03-22 13:13:39

+0

没有任何Domino对象被保留为bean的属性,所以就我所知,序列化不是问题。但是这个bean已经在viewScope中测试过了,结果相同。 – TrailDragon 2013-03-22 14:26:01

回答

1

首先看看您的服务器控制台:您是否看到NotesException?如果遇到例外情况,您的放入将永远不会执行,因此您的组合框将为空。

在你回收一个对象之前,你必须测试它是否为null,被try/catch块包围。有一些实现可以更轻松地回收Notes对象f.e.这一个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/

+0

感谢您的回复Sven。我了解回收的原因和问题(通常使用回收助手,因为清晰的原因,我没有在这段代码中加入),但Nathan的新文章对它的解释比我想象的要好。我忘记添加异常的细节,因为这已经让我烦恼了很多年 - 再次考虑,我认为这并不是关于NotesEntry对象的再循环,更多的是丢失了指向navData ViewNavigator对象的指针。我对这种情况发生的原因以及如何编写代码有绝对的头脑空白。 – TrailDragon 2013-03-22 14:30:58