此问题的根本原因是在
IndirectListEclipselink
JPA类中使用了错误的实现模式。(doc,source)在2.5版本家族中会发生此问题;它也可能在其他版本中出现。
问题在于,此类既是 子类
Vector, 又具有 对
Vector实例 的
引用。它尝试通过覆盖的所有方法来将所有方法调用委托给该实例
Vector。只要没有添加新方法,此方法就可以正常工作
Vector。
这发生在Java 8中。
Java的8增加了几个新 的默认方式 为
Collection,
Iterable和
List接口,包括:
forEach
parallelStream
removeIf
replaceAll
sort
spliterator
stream
通常,添加默认方法是安全的,因为必须根据其他现有方法来实现它们。但是,出于效率考虑,实现类覆盖默认方法通常是一个好主意。Java 8
Vector实现添加了这些默认方法的多个替代。如果您有实际
Vector类的实例,则这些方法可以正常工作。本
IndirectList类不重写这些方法,所以代表团路径,它试图建立不起作用了这些方法。而是使用普通的
Vector实现。不幸的是,这些
IndirectList方法不能使超类状态保持最新,因此
Vector这些方法的实现都表现为好像
Vector是空的。
Vector覆盖
forEach,
removeIf,
replaceAll,
sort,和
spliterator。在
parallelStream与
stream默认的方法是在以下方面实现的
spliterator,于是同样的事情发生在他们身上。本质上,如果在
IndirectList从Eclipselink
JPA检索的实现中使用集合上的新默认方法,则这些新方法都不起作用。
请注意,也会出现此问题
Collections.sort(indirectList)。此方法仅调用该
indirectList.sort()方法,因此遇到与上述完全相同的问题。
有关Eclipselink状态的更多信息,请参阅Eclipselink
JPA错误433075和446236。
有关此实现模式的陷阱的更多信息,请参见Joshua Bloch的书《 Effective Java,第二版 , 第16项:继承而不是继承》。



