Java 使用lotus.domino.Document作为函数的参数,如何干净地回收?
我正在编写一个服务器任务外接程序,并试图生成一个干净、可回收的代码。我正在循环浏览一组数据库,然后浏览数据库中的一些文档Java 使用lotus.domino.Document作为函数的参数,如何干净地回收?,java,lotus-notes,Java,Lotus Notes,我正在编写一个服务器任务外接程序,并试图生成一个干净、可回收的代码。我正在循环浏览一组数据库,然后浏览数据库中的一些文档 for (String serverAndFilename : listofServerFilenames) { String[] parts = serverAndFilename.split("!!"); currentGECDB = session.getDatabase(parts[0], parts[1]);
for (String serverAndFilename : listofServerFilenames) {
String[] parts = serverAndFilename.split("!!");
currentGECDB = session.getDatabase(parts[0], parts[1]);
if (currentGECDB.isOpen()) {
collSourceDocuments = currentGECDB.search(this
.getSearchFormula(this
.getvariablePartOfSearchFormula()));
countOfSearchDocuments = collSourceDocuments.getCount();
docToChange = collSourceDocuments
.getFirstDocument();
while (docToChange != null) {
if (changeNamesFieldsOnThisDocument(docToChange)) {
// .... other code here
}
tmpdoc = collSourceDocuments.getNextDocument();
docToChange.recycle();
docToChange = tmpdoc;
}
}
}
}
我关心的是使用重Notes项目作为Java函数的参数时的内存管理问题。在检查函数所做的更改时,我会获取“旧”值,需要在重新检索文档之前对文档进行循环()
在我看来,我被迫只将原语作为参数传递给外部函数,即
public booleanfunction (String ServerName, String ReplicaIDOfDatabase, String UNIDofDocument)
但这将意味着许多后续的OpenDatabase调用,这些调用非常昂贵
有没有最好的办法
例如,这是我对结果进行的JUnit测试的一部分:
public void testNewArrivalTaskExample() {
try {
testNewArrivalTask = GECTaskNewArrival.getTestTask(db, oli);
testNewArrivalTask.save();
Document testdocNewArrival_1 = getNewTestSourceCourrierDocument();
for (NamesItemsInProcedure n : NamesItemsInProcedure.values()) {
setNamesField(testdocNewArrival_1, n,
GECTaskNewArrival.NEW_ARRIVAL_ROLE_MODEL,
NamesItemsInProcedure.NOUVELLE_ARRIVEE);
}
testdocNewArrival_1.replaceItemValue("TestDocumentDescription",
"NewArrival_AllFields");
testdocNewArrival_1.save();
GECTaskNewArrival gna = new GECTaskNewArrival(testNewArrivalTask,
db, oli);
gna.process();
Item itemsuivi = testdocNewArrival_1
.getFirstItem(NamesItemsInProcedure.SUIVI_COURRIER
.getItemName());
System.out.println("Content of document without recycle + rebirth:");
printItemValuesToSysout(itemsuivi);
System.out.println(NamesItemsInProcedure.SUIVI_COURRIER
.getItemName()
+ " Should contain "
+ GECTaskNewArrival.NEW_ARRIVAL_NEWPERSON);
String noteID = testdocNewArrival_1.getNoteID();
testdocNewArrival_1.recycle();
for (NamesItemsInProcedure n : NamesItemsInProcedure.values()) {
boolean result = itemContainsThisForTestDoc(GECAlladin, noteID,
n.getItemName(),
GECTaskNewArrival.NEW_ARRIVAL_NEWPERSON);
switch (n) {
case ENCOURS_COURRIER:
assertTrue(result);
break;
case AUTEURS_COURRIER:
assertTrue(result);
break;
case SUIVI_COURRIER:
assertTrue(result);
break;
case ECHEANCEMESSAGENOM_COURRIER:
assertTrue(result);
break;
default:
// assertFalse(result);
break;
}
}
} catch (NotesException e) {
e.printStackTrace();
}
}
这是控制台结果:
Content of document without recycle + rebirth:
Suivi has these values:
Donald VieuxDeLaVieille/dsic/ville-ge`
the item belongs to this document 929E`
Suivi Should contain CN=Micky NouvelleArrivee/OU=salut/OU=Truc/O=Muche`
Suivi has these values:`
Donald VieuxDeLaVieille/dsic/ville-ge`
CN=Micky NouvelleArrivee/OU=salut/OU=Truc/O=Muche`
the item belongs to this document 929E`
Suivi contains CN=Micky NouvelleArrivee/OU=salut/OU=Truc/O=Muche`
我仍然感到困惑。您可以尝试从以下内容更改代码:
tmpdoc = collSourceDocuments.getNextDocument();
为此:
tmpdoc = collSourceDocuments.getNextDocument(docToChange);
根据doc,在getNextDocument调用中省略Document参数应该是可行的,但我的理解是,DocumentCollection内部有不同的实现,这取决于集合的构建方式,我认为省略Document参数可能会给您带来一些奇怪的结果(即,解释您看到的“旧”值)对于由Database.search()创建的DocumentCollection.我没有发现将NotesDocument对象传递给函数时出现任何问题的迹象。我经常这样做。“旧”值是什么意思?我从一个文档开始。项“状态”的值为“开始”。然后我对文档进行一些处理(将项更改为“结束”),保存()。当我使用ScanEZ查看数据库中的文档时,状态项的值为“Start”,正如我所期望的,但在我的代码中,当我执行'item=doc.getfirstitem(“状态”);String Status=item.getItemValueString(),答案是“开始”,而不是“结束”。如果我获取文档的NoteID,回收它,然后用NoteID重新加载它,那么我会得到“结束”,也许上面有一个拼写错误?如果ScanEZ说值是“开始”,而getItemValueString()给你“开始”,这似乎是正确的行为。或者至少是一致的行为。你真的想说ScanEZ说的值是“结束”吗?你能在一小段代理代码中复制它吗?Richard,我已经包含了一个我正在使用的JUnit测试的示例。因此,为了确保我理解……你是说文档testdocNewArrival_1中的“suivi”项已更新,文档保存在函数setNamesField()中,但在函数返回并执行新的itemsuivi=GetFirstItem(“suivi”)之后,然后调用printItemValuesToSysout(),并且没有显示更新后的值。因此内存中的文档对象没有新值。但是,在您回收testdocNewArrival_1并调用ItemContains for ListStDoc并按NoteID重新加载文档后,新的内存中文档对象确实有新值。这非常奇怪。感谢您的提示,Richard。我更关心
if(更改此文档的名称字段(docToChange))
line。我正在发送一个文档作为参数,它会生成引用的副本,不是吗?不,它是对象引用的副本,但引用是指向同一个文档对象。后端类确保每个文档对象只有一个内存分配,不管对同一文档对象有多少引用其他Notes对象类型也是如此,如果您不小心的话,这就是为什么一个函数中的代码可以回收一个文档,或者从另一个仍然需要它的文档中的代码下查看—这在多线程代码中是一个特别危险的问题。我已经按照您所描述的更改了代码,但是,唉!改为n哦,有用。