stream on JPA lazy list
Apparently, you are referring to this issue. These lazy lists using the anti-pattern of inheriting from actual implementations (here Vector
) fail to adapt to the evolution of the base class. Note that there are two possible outcomes depending on how the anti-pattern was realized
- If the lazily populated list populates itself (it terms of the inherited state) on the first use, the new inherited methods will start working as soon as a trigger property has been accessed for the first time
- But if the list overrides all accessor methods to enforce delegation to another implementation, without ever updating the state of the base class, the base class’ methods which have not been overridden will never start working, even if the list has been populated (from the subclass’ point of view)
Apparently, the second case applies to you. Triggering the population of the list does not make the inherited forEach
method work. Note that turning off the lazy population via configuration might be the simpler solution here.
To me, the cleanest solution would be if IndirectList
inherits from AbstractList
and adheres to the Collection API standard, now, almost twenty years after the Collection API has superseded Vector
(should I mention how much younger JPA actually is?). Unfortunately, the developers didn’t go that road. Instead, the anti-pattern was maxed out by creating another class that inherits from the class which already inherits from the class not designed for inheritance. This class overrides the methods introduced in Java 8 and perhaps gets another subclass in one of the next Java releases.
So the good news is, developers expecting every List
to be a Vector
do not have to make up their minds, but the bad news is it doesn’t work as sometimes, you will not get the extended Java 8 specific version with JPA 2.6. But apparently, JPA 2.7 will work.
So you can derive a few alternative solutions:
- Turn off lazy population
- Stay with Java 7
- Wait for JPA 2.7
- just copy the collection, e.g.
List<ElementParameter> workList=new ArrayList<>(elementParameters);
ThisworkList
will support all Collection & Stream operations