在JPA惰性列表上流

Simo:

我有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提供程序。

霍尔格:

显然,您是指此问题这些使用从实际实现(在此处Vector继承的反模式的懒惰列表无法适应基类的发展。请注意,取决于实现反模式的方式,有两种可能的结果

  • 如果延迟填充的列表在首次使用时填充自身(继承状态的术语),则在首次访问触发器属性后,新的继承方法将开始工作
  • 但是,如果列表覆盖了所有访问器方法以强制委派其他实现,而又不更新基类的状态,则即使已填充列表(从列表中填充),未被覆盖的基类的方法也将永远无法开始工作。子类的观点)

显然,第二种情况适用于您。触发列表的填充不会使继承的forEach方法起作用。请注意,此处通过配置关闭惰性填充可能是更简单的解决方案。


对我而言,最干净的解决方案是,如果现在IndirectList继承AbstractListCollection Collection API并遵守Collection API标准,那么将近二十年Vector(我应该说JPA实际上是多少?)。不幸的是,开发人员并没有走这条路。相反,通过创建另一个从该类继承的类来最大化反模式,该类已经从非继承设计类继承而来。此类重写Java 8中引入的方法,并且可能在下一Java版本中获得另一个子类。

因此,好消息是,开发者希望每一个List是一个Vector没有拿定主意,但坏消息是这是行不通的,因为有时候,你会不会使用JPA 2.6得到扩展的Java 8特定版本。但显然,JPA 2.7可以使用。

因此,您可以得出一些替代解决方案:

  • 关闭懒惰的人群
  • 坚持使用Java 7
  • 等待JPA 2.7
  • 刚才复制的集合,例如
    List<ElementParameter> workList=new ArrayList<>(elementParameters);
    workList将支持所有采集与流操作

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章