我有JPA实体,列表如下:
@OneToMany(mappedBy = "scadaElement", orphanRemoval = true)
private List<ElementParameter> elementParameters;
并映射表单ElementParameter
@ManyToOne
@JoinColumn(name = "SCADAELEMENT_ID")
ScadaElement scadaElement;
当我获得带有elementParameters列表的实体并对其执行流时,即使我使用.size()触发列表时,也不执行任何操作,但是当我使用for循环执行相同操作时,它可以正常工作。
System.out.println("elements size: " + s.getElementParameters().size());
s.getElementParameters()
.stream()
.forEach(
a -> {
System.out.println("elementId: " + a.getId());
}
);
是否有任何解决方案可以使该流有效?我使用eclipselink作为JPA提供者。
答案 0 :(得分:6)
显然,你指的是this issue。这些使用从实际实现继承的反模式(此处为Vector
)的惰性列表无法适应基类的演变。请注意,根据反模式的实现方式,有两种可能的结果
显然,第二种情况适用于您。触发列表的填充不会使继承的forEach
方法起作用。请注意,通过配置关闭延迟填充可能是更简单的解决方案。
对我而言,最简洁的解决方案是IndirectList
继承自AbstractList
并遵守Collection API标准,现在,在Collection API取代Vector
差不多20年后(应该我提到JPA实际上有多少年了?)。不幸的是,开发人员没有走那条路。相反,反模式通过创建另一个继承自已继承自未设计用于继承的类的类的类来最大化。该类重写了Java 8中引入的方法,并且可能在下一个Java发行版中获得另一个子类。
所以好消息是,开发人员希望每个List
成为Vector
都不必下定决心,但坏消息是it doesn’t work,有时,你不会使用JPA 2.6获得扩展的Java 8特定版本。但显然,JPA 2.7将起作用。
所以你可以推导出一些替代解决方案:
List<ElementParameter> workList=new ArrayList<>(elementParameters);
workList
将支持所有收藏和收集。流操作答案 1 :(得分:0)
为什么不使用real JPA Streaming?
Stream<User> findAllByName(String name);