Как предотвратить несколько вызовов RPC RunQuery для одного JDO Query execute()?

Я настроил Appstats в своем приложении Java Appengine и заметил, что один запрос JDO, который возвращает несколько объектов, приводит к отдельному RPC-вызову RunQuery для каждого объекта, полученного запросом.

Разве запрос не должен выполняться в одном вызове RPC?

Я пытался настроить Fetchgroups и Fetchplans, чтобы попытаться избежать этого, но безрезультатно.

Мой код выглядит примерно так:

Query query = pm.newQuery(WidgetDSO.class);

String filter = "widgetId == param1 || widgetId == param2 || widgetId == param3";
String parameters = "String param1, String param2, String param3";

query.setFilter(filter.toString());
query.declareParameters(parameters.toString());

List<WidgetDSO> results = (List<WidgetDSO>) query.executeWithArray(widgetIds);
if (!results.isEmpty()) 
...

Когда это выполняется, Appstats сообщает мне, что последняя строка results.isEmpty() приводит к такому количеству вызовов RPC, как количество полученных объектов:

@104ms datastore_v3.RunQuery real=5ms api=21ms
@422ms datastore_v3.RunQuery real=4ms api=12ms
@428ms datastore_v3.RunQuery real=4ms api=12ms
@434ms datastore_v3.RunQuery real=3ms api=12ms
@439ms datastore_v3.RunQuery real=4ms api=12ms
@445ms datastore_v3.RunQuery real=4ms api=12ms
@451ms datastore_v3.RunQuery real=4ms api=21ms
@463ms datastore_v3.RunQuery real=5ms api=21ms

Трассировка стека для каждого из этих вызовов одинакова (только частичная трассировка стека):

com.google.appengine.tools.appstats.Recorder:290 makeAsyncCall()
com.google.apphosting.api.ApiProxy:184 makeAsyncCall()
com.google.appengine.api.datastore.DatastoreApiHelper:81 makeAsyncCall()
com.google.appengine.api.datastore.PreparedQueryImpl:144 runQuery()
com.google.appengine.api.datastore.PreparedQueryImpl:70 asIterator()
com.google.appengine.api.datastore.PreparedMultiQuery$FilteredMultiQueryIterator:165 getNextIterator()
com.google.appengine.api.datastore.PreparedMultiQuery$FilteredMultiQueryIterator:184 computeNext()
com.google.appengine.api.datastore.PreparedMultiQuery$FilteredMultiQueryIterator:98 computeNext()
com.google.appengine.api.datastore.AbstractIterator:52 tryToComputeNext()
com.google.appengine.api.datastore.AbstractIterator:47 hasNext()
com.google.appengine.api.datastore.BasePreparedQuery$UncompilablePreparedQuery$1:86 hasNext()
org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator$1:50 get()
org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator$1:46 get()
org.datanucleus.store.appengine.query.QueryExceptionWrappers$1:51 get()
org.datanucleus.store.appengine.query.QueryExceptionWrappers$2:86 get()
org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator:105 hasNext()
org.datanucleus.store.appengine.query.LazyResult:115 resolveAll()
org.datanucleus.store.appengine.query.LazyResult:110 size()
org.datanucleus.store.appengine.query.StreamingQueryResult:130 size()
org.datanucleus.store.query.AbstractQueryResult:312 isEmpty()
org.instantplaces.im.server.dso.WidgetDSO:209 getWidgetsFromDSO()
org.instantplaces.im.server.resource.WidgetResource:239 doDelete()
org.instantplaces.im.server.resource.GenericResource:244 delete()

Есть ли способ получить все объекты всего за один вызов?


person Jorge Cardoso    schedule 31.10.2011    source источник


Ответы (1)


Это ваш точный код? Если это так, я бы ожидал как минимум 3 запроса, минимум. Родного "||" нет ("ИЛИ") запрос в хранилище данных. JDO вынужден преобразовать ваш запрос в один запрос для каждой опции. Дополнительную информацию см. в документах и связанная запись в блоге. Это не указано прямо - вам нужно объединить тот факт, что || превращаются в .contains(), а .contains() требует нескольких get.

|| является допустимым только в тех случаях, когда фильтры, которые он разделяет, могут быть объединены в один фильтр contains():

а также

Оператор contains() также выполняет несколько запросов, по одному для каждого элемента в предоставленном значении списка, где все остальные фильтры одинаковы, а фильтр contains() заменяется фильтром, равным.

person Peter Recore    schedule 01.11.2011