2013-03-22 57 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