在 JPA 惰性列表上流式传输 [英] stream on JPA lazy list

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

问题描述

我有这样的列表的 JPA 实体:

I have JPA entity with list like this:

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

和映射表单元素参数

@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.

所以好消息是,希望每个 List 都是 Vector 的开发人员不必下定决心,但坏消息是 它不起作用 因为有时,您不会获得扩展的 Java 8 特定版本使用 JPA 2.6.但显然,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
  • 只需复制集合,例如
    <代码>列表<元素参数>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天全站免登陆