Java Hibernate/JPA刷新整个集合
我有一个Java Hibernate/JPA刷新整个集合,java,hibernate,jpa,jpa-2.0,Java,Hibernate,Jpa,Jpa 2.0,我有一个惰性负载@OneToMany @JsonIgnore @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) private List<OrderItem> orderItems = new ArrayList<>(); 我认为这不是很有效,因为它试图一个接一个地刷新实体,这意味着
惰性负载
@OneToMany
@JsonIgnore
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private List<OrderItem> orderItems = new ArrayList<>();
我认为这不是很有效,因为它试图一个接一个地刷新实体,这意味着它一个接一个地激发SQL
我相信hibernate是如何工作的,当我们调用代理包装器getOrderItems
时,只需启动一个SQL就可以通过父级的外键选择记录。这样更有效
我可以用这种方式刷新整个列表吗?我怀疑是否可以让entityManager用一条语句或一条SQL刷新整个集合。我认为如果JPA提供了这样的功能,并通过基于父ID发出一个SQL来表示刷新,那就太好了 refresh()方法要求我们传递一个托管实体。因此,我们不能将列表直接传递给此方法。因此,我看到的其他两个选择是:
如果不使用二级缓存,请使用命名查询来获取父实体和子关系。与逐个刷新每个成员相比,这将大大提高效率 最酷的事情是,命名查询将绕过一级缓存
如果您使用二级缓存,则需要先逐出实体。请解释为什么需要刷新实体?为什么不刷新父实体,或者完全取消事务?您所指的长操作是否已包装在事务中?@crizzis refresh parent entity将刷新子操作?我检查了级联类型,没有这样的选项。是的,长操作意味着它被包装在一个事务中。
ALL=DETACH、MERGE、PERSIST、REFRESH、REMOVE
@crizzis我明白了。。这是我的错。。。我在这里忽略了@crizzis,所以通过刷新父对象,hibernate应该立即刷新集合,对吗?而不是逐个刷新子实体。调用refresh
将导致放弃对列表中实体所做的更改<代码>合并将导致完全相反的结果。在上述情况下,应特别注意副作用scenario@crizzis我的错误是,我的意思是对父实体调用刷新,而不是合并。更新。谢谢
for (OrderItem orderItem : order.getOrderItems()) {
entityManager.refresh(orderItem);
}