Stream over a lazy JPA list

I have a JPA object with a list like this:

@OneToMany(mappedBy = "scadaElement", orphanRemoval = true) private List<ElementParameter> elementParameters; 

and shape of the ElementParameter map

 @ManyToOne @JoinColumn(name = "SCADAELEMENT_ID") ScadaElement scadaElement; 

when I get an object with a list of elementParameters and do a thread over it, it does nothing, even when I run the list with .size (), but when I do the same with the for loop, it works.

 System.out.println("elements size: " + s.getElementParameters().size()); s.getElementParameters() .stream() .forEach( a -> { System.out.println("elementId: " + a.getId()); } ); 

Is there any solution for this thread to work? I use eclipselink as a JPA provider.

+6
source share
1 answer

Apparently you mean this problem . These lazy lists using the anti-inheritance pattern from real implementations (here Vector ) cannot adapt to the evolution of the base class. Please note that there are two possible outcomes depending on how the anti-pattern is implemented.

  • If in the first use the list of lazily populated (its terms of the inherited state) is populated, the new inherited methods will start working immediately after accessing the trigger property for the first time
  • But if a list overrides all access methods to force delegation to another implementation without updating the state of the base class, methods of the base class that have not been redefined will never start working, even if this list has been populated (from a subclass)

Apparently the second case applies to you. Running a list pop does not result in an inherited forEach method. Note that disabling a lazy population through configuration may be a simpler solution here.


For me, the cleanest solution would be if IndirectList inherits from AbstractList and adheres to the API Collection standard, now, almost twenty years after the API Collection has replaced Vector (should I mention how much younger the JPA actually is?). Unfortunately, the developers did not follow this road. Instead, the anti-pattern was maximized by creating another class that inherits from a class that already inherits from a class not intended to be inherited. This class overrides the methods introduced in Java 8, and possibly gets another subclass in one of the next releases of Java.

So the good news is that developers who expect each List be Vector should not solve them, but the bad news is that it does not work , because sometimes you will not get an extended version of Java 8 with JPA 2.6. But apparently JPA 2.7 will work.

So, you can get some alternative solutions:

  • Disable lazy population
  • Stay with Java 7
  • Wait JPA 2.7
  • just copy the collection for example
    List<ElementParameter> workList=new ArrayList<>(elementParameters);
    This workList will support all Collection and Stream operations.
+6
source

All Articles