我有一個會話scoped bean,它讀取視圖的內容並存儲SelectItem對象的散列表。這些被用來在XPage上填充組合框值。在Domino對象上使用回收會導致Bean不返回數據
代碼工作正常,除非我嘗試回收最內層循環中的ViewEntry對象。如果該行被註釋掉,我的SelectItems返回正常。如果該行沒有註釋,我的組合框就是空的。所以我想知道的是:
- 爲什麼會發生這種情況?
- 我該如何解決這個問題並像一個好的開發人員那樣正確地回收對象?
- 如果我不能明確地回收對象,對內存等的潛在影響是什麼?
代碼(有問題的行強調,目前註釋掉):
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的指針,否則它將使用該參數。
我責怪週五。
Domino對象不能被序列化。因此,不能保證代碼將按預期工作,並將其放入sessionScope中。 – 2013-03-22 13:13:39
沒有任何Domino對象被保留爲bean的屬性,所以就我所知,序列化不是問題。但是這個bean已經在viewScope中測試過了,結果相同。 – TrailDragon 2013-03-22 14:26:01