2010-05-20 102 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) 

我试图从数据存储查询中获取一个列表,并且只保留列表中的结果,这些列表也是从列表中检索的。我的列表都按预期填充,但我似乎无法在其中任何一个上使用retainAll。什么导致这个retainAll异常?

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

编辑

好吧,企图简化,因为这是一个明显多问题,我一直在使用的数据存储的底层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

奇怪,你确定你使用'新的ArrayList()'把元素在新数组列表? stacktrace表明你没有为'listTwo'使用'new ArrayList()'。 – BalusC 2010-05-20 01:14:31

+0

对不起,我删掉了一些代码,以保持简单。我在之前将listOne定义为新的ArrayList,然后将查询转换为ArrayList。它不会让我在查询结果上执行新的ArrayList(),因为它返回一个对象数组。 – Joren 2010-05-20 01:16:35

回答

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); 

更新:根据您的更新,实体显然延迟加载/填充。大多数ORM(DataNucleus就是其中之一)的确可以做到这一点。因为我不使用DataNucleus,所以我不能详细说明如何以“很好”的方式解决这个问题。但是你至少现在知道问题的根本原因,并且可以用与上述相同的方式解决。在循环中填写列表test

+0

嗯,ds.get让我创建一个新的ArrayList。我发现它不会让我从Entity转换到我的对象类型。我无法弄清楚如何将一个实体变成其他任何东西。 另外,非常奇怪的是,如果在我演员列表之后我做了\t \t log.info(listOne.toString());我没有得到UnsupportedOperationException。如果我不打电话给log.info,我得到错误。我不知道那是怎么回事。 – Joren 2010-05-20 02:01:49

+0

我看到了,我更新了答案。 – BalusC 2010-05-20 02:40:48

+0

Oy。好吧,它终于工作。我希望有人会用手工构建列表的方式来解决这个问题,但现在它可以工作。谢谢! – Joren 2010-05-20 02:51:45

1

如果您用于“键列表”收集的类型不支持retainAll这将引发异常。你使用哪种类型?

+0

这两个列表的ArrayList。 – Joren 2010-05-20 01:17:14

0

提示:你不需要迭代来填充listTwo。 只是做:

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

相关问题