Morphia / MongoDB: не могу сделать больше - PullRequest
1 голос
/ 06 февраля 2011

Я пытаюсь перебрать все строки («документы»?) В моей базе данных MongoDB, используя Morphia.Иногда я получаю следующую трассировку стека:

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?Моя ошибка?

Обновление:

Я также вижу это в моих журналах Glassfish:

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

Ответы [ 3 ]

1 голос
/ 12 февраля 2011

Это действительный код? Кажется очень маловероятным, что этот код вызовет это исключение. Тайм-аут курсора после 10 минут бездействия. С такой плотной петлей это кажется невозможным.

Вы можете использовать datastore.createQuery(App.class).disableTimeout()..., чтобы отключить тайм-аут курсора в Morphia. Вы также можете использовать datastore.createQuery(App.class).fetchEmptyEntities(), если хотите просто заполнить поле @Id.

Кроме того, нет необходимости явно вызывать fetch(), если вы просто хотите использовать итератор в цикле for, подобном этому; fetch просто необходим, когда вы хотите сохранить итератор в переменной и использовать его в нескольких местах, но не в одном цикле for.

1 голос
/ 30 мая 2011

Просто столкнулся с той же проблемой во время итерации очень большого запроса. Я обнаружил эту ошибку Morphia, о которой было сообщено 21 марта 2011 года:

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

Проблема 251: включение / отключение тайм-аута противоположно тому, что говорится

Проблема говорит, что это будет исправлено в версии 1.0. Новый API disableCursorTimeout() представлен в 1.00-SNAPHSHOT. Я запускаю тест long , чтобы посмотреть, решит ли он проблему.

1 голос
/ 07 февраля 2011

Как вы можете видеть в этой теме MongoDB освобождает курсор через определенное время. Возможным решением может быть эмуляция пакетной итерации и обновление курсора в и из цикла.

...