2010-05-20 5 views
4
java.lang.UnsupportedOperationException: This operation is not supported on Query Results 
    at org.datanucleus.store.query.AbstractQueryResult.contains(AbstractQueryResult.java:250) 
    at java.util.AbstractCollection.retainAll(AbstractCollection.java:369) 
    at namespace.MyServlet.doGet(MyServlet.java:101) 

Я пытаюсь взять один список, который я извлек из запроса хранилища данных, и сохранить только те результаты, которые также находятся в списке, который я получил из списка ключей. Оба моих списка заполняются так, как ожидалось, но я не могу, по-видимому, удержать пользователя на любом из них.В чем причина этого исключения?

//   List<Data> listOne = new ArrayList(query.execute(theQuery)); 
//   DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); 
//   List<Data> listTwo = new ArrayList(ds.get(keys).values()); 
//   listOne.retainAll(listTwo); 

EDIT

Ok, в попытке упростить, так как это, по-видимому несколько проблем в одном, я перестал использовать низкий уровень API для хранилища данных и вместо утра просто потянув один за другим с петля.

   List<MyClass> test = (List<MyClass>) query.execute(); 
       List<MyClass> test2 = new ArrayList<MyClass>(); 

       for (String key : favorites) { 
        test2.add(pm.getObjectById(MyClass.class, key)); 
       } 

       log.info(test.toString()); 
       test.retainAll(test2); 

Указанные работы. Это не исключение. Ниже приведено исключение. Единственное отличие - log.info. Я в тупике.

   List<MyClass> test = (List<MyClass>) query.execute(); 
       List<MyClass> test2 = new ArrayList<MyClass>(); 

       for (String key : favorites) { 
        test2.add(pm.getObjectById(MyClass.class, key)); 
       } 

       test.retainAll(test2); 
+1

Weird, вы уверены, что вы использовали 'новый ArrayList()', чтобы поместить элементы в новый ArrayList? Стекло указывает, что вы не использовали 'new ArrayList()' для 'listTwo'. – BalusC

+0

Извините, я вырезал код, чтобы он был простым. Я определяю listOne раньше как новый ArrayList, а затем бросаю запрос в ArrayList. Это не позволит мне сделать новый ArrayList() в результате запроса, так как он возвращает массив объектов. – Joren

ответ

2

Это не позволит мне сделать новый ArrayList() в результате запроса, так как он возвращает массив объектов.

Вам, однако, необходимо поставить их в new ArrayList(). Возвращенная версия List, по-видимому, не поддерживает retainAll(). Вот что говорит вам исключение.

«Обычный» ArrayList поддерживает его. Если прохождение через конструктор ArrayList невозможно из-за различий в родовом типе, вам нужно будет вручную перебрать его и бросить каждый элемент перед добавлением.

List<Data> listTwo = new ArrayList<Data>(); 
for (Object object : ds.get(keys).values()) { 
    listTwo.add((Data) object); 
} 
listOne.retainAll(listTwo); 

Update: согласно вашему обновления, сущности, по-видимому, лениво загружены/заполнены. Большинство ORM (DataNucleus - это одно) действительно могут это сделать. Поскольку я не использую DataNucleus, я не могу подробно рассказать о том, как исправить это «красивым» способом. Но вы, по крайней мере, теперь знаете основную причину проблемы, и ее можно решить так же, как описано выше. Заполните также список test.

+0

Хм, ds.get позволяет мне создать новый ArrayList. Я обнаружил, что это не позволит мне отбрасывать из Entity в мой тип объекта. Я не могу понять, как превратить сущность во что-то еще. Кроме того, очень странно, если после того, как я бросил listOne, я делаю \t \t log.info (listOne.toString()); Я не получаю исключение UnsupportedOperationException. Если я не вызываю log.info, я получаю ошибку. Я понятия не имею, что с этим. – Joren

+0

Вижу, я обновил ответ. – BalusC

+0

Oy.Хорошо, он работает наконец. Я надеюсь, что кто-то купит менее глупое решение, чем вручную, создав список, но пока это работает. Благодаря! – Joren

1

Если тип коллекции вы используете для «список ключей» не поддерживает retainAll, что будет сгенерировано исключение. Какой тип вы используете?

+0

ArrayList для обоих списков. – Joren

0

СОВЕТ: вам не нужно перебирать список, чтобы заполнить список. просто сделать:

listTwo.addAll(ds.get(keys).values())

Смежные вопросы