Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Morphia/MongoDB:can';不要做更多的事_Java_Mongodb_Morphia - Fatal编程技术网

Java Morphia/MongoDB:can';不要做更多的事

Java Morphia/MongoDB:can';不要做更多的事,java,mongodb,morphia,Java,Mongodb,Morphia,我正在尝试使用Morphia迭代MongoDB数据库中的所有行(“文档”)。偶尔我会得到以下堆栈跟踪: com.mongodb.MongoInternalException: can't do getmore at com.mongodb.DBApiLayer$Result._advance(DBApiLayer.java:378) at com.mongodb.DBApiLayer$Result.hasNext(DBApiLayer.java:356) at com.m

我正在尝试使用Morphia迭代MongoDB数据库中的所有行(“文档”)。偶尔我会得到以下堆栈跟踪:

com.mongodb.MongoInternalException: can't do getmore
    at com.mongodb.DBApiLayer$Result._advance(DBApiLayer.java:378)
    at com.mongodb.DBApiLayer$Result.hasNext(DBApiLayer.java:356)
    at com.mongodb.DBCursor._hasNext(DBCursor.java:436)
    at com.mongodb.DBCursor.hasNext(DBCursor.java:456)
    at com.google.code.morphia.query.MorphiaIterator.hasNext(MorphiaIterator.java:40)
    at 
在MongoDB日志文件中,我看到以下内容:

$ grep "cursorid not found" output.log 
Sun Feb  6 12:14:35 [conn13] getMore: cursorid not found App 2079575931792020691
Sun Feb  6 12:44:17 [conn19] getMore: cursorid not found App 8364953818630631317
Sun Feb  6 13:08:42 [conn20] getMore: cursorid not found App 7142256996888968009
我的迭代代码非常简单:

    for (App app : datastore.createQuery(App.class).fetch())
    {
        log.info("app: " + app.getId());
        // do stuff with app
    }
吗啡虫?MongoDB臭虫?我的虫子

更新:

我在玻璃鱼日志中也看到了这一点:

[#|2011-02-16T15:39:58.029+0000|WARNING|glassfish3.0.1|com.mongodb.TRACE|_ThreadID=28;_ThreadName=Thread-1;|The log message is null.
java.lang.NullPointerException
    at com.mongodb.DBApiLayer._cleanCursors(DBApiLayer.java:113)
    at com.mongodb.DBApiLayer$DBCleanerThread.run(DBApiLayer.java:494)
    at java.lang.Thread.run(Thread.java:662)

正如您在本文中看到的,MongoDB在一定时间后释放游标。一个可能的解决方案可能是模拟批处理迭代,并在循环的和处更新光标。

这是实际代码吗?这段代码似乎不太可能产生这种异常。10分钟不活动后,游标超时。像这样的紧密循环似乎是不可能的

您可以使用
datastore.createQuery(App.class).disableTimeout()…
在Morphia中禁用光标超时。如果只想填写
@Id
字段,还可以使用
datastore.createQuery(App.class).fetchEmptyEntities()


此外,如果您只想在这样的for循环中使用迭代器,则无需显式调用
fetch()
;当您想将迭代器存储在一个变量中并在多个位置使用它,而不是在单个for循环中使用它时,只需要fetch。

在迭代一个非常大的查询时遇到了相同的问题。我在2011年3月21日发现了这个Morphia bug:

问题251:启用/禁用超时与它所说的相反


该问题称将在1.0版中修复。新的API
disableCursorTimeout()
在1.00-SNAPHSHOT中公开。我正在运行一个长时间的测试,看看它是否解决了问题。

我在提出问题时尽量简化代码,因此我遗漏了可能有用的信息,您是对的。在“用应用程序做事情”中发生的是:查询web服务并将结果保存到磁盘上的文件中。这通常以毫秒为单位执行,但我将向循环中添加一些时间检查,看看是否存在导致超时的异常行为。谢谢。刚刚做了几轮测试,了解到超时发生在迭代过程的45分钟内,这是可以重复的。请注意,每次通过迭代循环的时间通常小于1秒,因此这似乎是整个迭代过程的超时,而不是每次调用Iterator.next()之间的延迟。这并不是那么简单。游标迭代器从服务器批量获取数据;对next()的每次调用可能需要与服务器对话,也可能不需要(批量大小可能为200+)。您是否尝试过disableTimeout选项?disableTimeout()似乎正在工作。在我使用迭代器之后,现在超时被禁用了,我是否需要做一些特殊的事情来释放迭代器?请注意,即使使用disableTimeout,迭代器仍然失败。