George Armhold
George Armhold

Reputation: 31064

Morphia/MongoDB: can't do getmore

I'm trying to iterate over all rows ("documents"?) in my MongoDB database using Morphia. Occasionally I get the following stacktrace:

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 

In the MongoDB log file I see the following:

$ 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

My code for iterating is pretty straightforward:

    for (App app : datastore.createQuery(App.class).fetch())
    {
        log.info("app: " + app.getId());
        // do stuff with app
    }

Morphia bug? MongoDB bug? My bug?

Update:

I'm also seeing this in my glassfish logs:

[#|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)

Upvotes: 1

Views: 2702

Answers (3)

joeymink
joeymink

Reputation: 88

Just ran into the same problem while iterating through a very large Query. I found this Morphia bug, reported on Mar 21, 2011:

http://code.google.com/p/morphia/issues/detail?id=251

Issue 251: enable/disable timeout does the opposite of what it says

The issue says it will be fixed in version 1.0. The new API disableCursorTimeout() is exposed in 1.00-SNAPHSHOT. I'm running a long test to see if it fixes the problem.

Upvotes: 1

Scott Hernandez
Scott Hernandez

Reputation: 7590

Is that the actual code? It seems very unlikely that that code would produce that exception. Cursors timeout after 10 minutes of inactivity. With a tight loop like that it seems impossible.

You can use datastore.createQuery(App.class).disableTimeout()... to disable the cursor timeout in Morphia. You can also use datastore.createQuery(App.class).fetchEmptyEntities() if you just want the @Id field filled in.

Also, there is no need to explicitly call fetch() if you just want to use the iterator in a for-loop like that; fetch is just needed when you want to store the iterator in a variable and use it in multiple places, but not in a single for-loop.

Upvotes: 1

Juraj Blahunka
Juraj Blahunka

Reputation: 18523

As you can see in this thread MongoDB releases cursor after a certain amount of time. A possible solution might be to do emulate batch iteration and renew the cursor at the and of the cycle.

Upvotes: 1

Related Questions