JPA懒惰列表上的流 [英] stream on JPA lazy list

查看:115
本文介绍了JPA懒惰列表上的流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有JPA实体,其列表如下:

I have JPA entity with list like this:

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

和地图表格ElementParameter

and map form ElementParameter

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

当我获得带有elementParameters列表的实体并在其上执行流时,流无效,即使我触发列表使用.size(),但是当我使用for循环执行相同操作时。

when i get entity with elementParameters list and do stream on it stream do nothing, even when I trigger list with .size() but when I do the same with a for loop it work.

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

是否有任何解决方案使该流有效?我使用eclipselink作为JPA提供者。

Is there any solution to make that stream work? I use eclipselink as JPA provider.

推荐答案

显然,你指的是这个问题。使用从实际实现继承的反模式(这里 Vector )的这些惰性列表无法适应基类的演变。请注意,根据反模式的实现方式,有两种可能的结果

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


  • 如果人工填充的列表填充了自己(它的条款是继承状态)第一次使用时,新的继承方法将在第一次访问触发器属性时立即开始工作

  • 但是如果列表覆盖所有访问器方法以强制执行到另一个实现,没有更新基类的状态,基类的方法没有被覆盖将永远不会开始工作,即使已经填充了列表(从子类的角度来看)

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

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.

对我来说,最干净的解决方案是如果 IndirectList 继承自 AbstractList 并且遵守Collection API标准,现在,在Collection API被取代后将近20年 Vector (我应该提一下年轻的JPA实际上是多少?)。不幸的是,开发人员没有走那条路。相反,反模式通过创建另一个继承自已继承自未设计用于继承的类的类的类来最大化。这个类重写了Java 8中引入的方法,并且可能在下一个Java版本中获得另一个子类。

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.

所以好消息是,开发人员期望每个列表向量不必下定决心,但坏消息是它不起作用,因为有时候,你不会得到带有JPA 2.6的扩展Java 8特定版本。但显然,JPA 2.7会起作用。

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:


  • 关闭懒惰人口

  • 留待Java 7

  • 等待JPA 2.7

  • 复制集合,例如

    List< ElementParameter> workList = new ArrayList<>(elementParameters);

    这个 workList 将支持所有Collection&流操作

  • 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);
    This workList will support all Collection & Stream operations

这篇关于JPA懒惰列表上的流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆