在 JPA 惰性列表上流式传输 [英] stream on JPA lazy list
问题描述
我有这样的列表的 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);
ThisworkList
will support all Collection & Stream operations
这篇关于在 JPA 惰性列表上流式传输的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!