我有一个会话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