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哦,有用。