Java JPA CascadeType.REFRESH不工作?
我在JPA CascadeType.REFRESH属性方面遇到了一个奇怪的问题。 我有一个简单的父子关系,其中在父域对象(LineEquipmentFormat)中添加了如下级联属性Java JPA CascadeType.REFRESH不工作?,java,jpa,Java,Jpa,我在JPA CascadeType.REFRESH属性方面遇到了一个奇怪的问题。 我有一个简单的父子关系,其中在父域对象(LineEquipmentFormat)中添加了如下级联属性 OneToMany(cascade = { CascadeType.REFRESH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy = "lineEquipmentFormat") public List<L
OneToMany(cascade = { CascadeType.REFRESH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REMOVE}, mappedBy = "lineEquipmentFormat")
public List<LineEquipmentFormatDivision> getLineEquipmentFormatDivisions() {
return lineEquipmentFormatDivisions;
}
我正在使用JBoos5.1和Oracle10g
请提供有关此错误可能根本原因的更多信息
感谢您将级联类型定义为refresh,这意味着在父LineEquipmentFormat上调用entityManager.refresh()时,子LineEquipmentFormatDivisions上也将调用entityManager.refresh()。但是,您收到的错误表明您试图在会话关闭时延迟初始化集合。如果在会话关闭后需要此集合,则需要通过设置fetchType急切地获取它们 我添加了如下所示的级联属性(…),但当我从DB获取父LineEquipmentFormat对象时,我没有得到LineEquipmentFormatDivisions的列表 级联操作与即时或延迟加载没有什么关系,在您的情况下,您得到的错误(臭名昭著的
LazyInitializationException
)意味着您试图访问延迟关联,但会话已经关闭(因此Hibernate无法加载它)
要避免此“问题”,请执行以下操作之一:
- 使用
属性加载关联(如果在大多数情况下不需要关联,我会在猪身上涂上口红)fetchType
- 对于此特定用例,使用
在执行查询时获取关联,例如:FETCH JOIN
SELECT f FROM LineEquipmentFormat f LEFT JOIN FETCH f.lineEquipmentFormatDivisions WHERE f.id = 1
- 使用openentitymanager-In-View模式(在MVC上下文中)在请求传入时打开实体管理器,并将其保持打开状态,直到请求得到处理(Spring有一个或一个实现此模式的接口)
- 在获取“LineEquipmentFormat”父对象时,我们添加了以下附加代码。
LineEquipmentFormat lef=entityManager.find(LineEquipmentFormat.class,sysId);
if(lef!=null&&lef.getLineEquipmentFormatDivisions()!=null){
lef.getLineEquipmentFormatDivisions().size();
}
返回lef - 现在,如果我们可以从这个父对象获取子列表
- 谢谢您的评论
下面是我们最终实现它的方式
但我没听明白你的话。如果我在一个事务中提取LineEquipmentFormat,并立即在下一行获取分区列表,那么会话肯定没有关闭吗?我们也不鼓励使用fetchType属性,这样就排除了该选项!如果每次初始化父对象时都需要子成员,那么将fetchType设置为eager就没有问题。如果不是这样的话,那么只有在需要它们时,才需要急切地获取它们,您可以使用fetchjoin对它们进行查询。如果您在查询LineEquipmentFormat和尝试访问LineEquipmentFormatDivisions的位置发布代码,我们可能会更有帮助。例如,如果您说的是entityManager.find(LineEquipmentFormat.class,id),则会话将在此方法中打开和关闭。您应该使用FETCH JOIN
SELECT f
FROM LineEquipmentFormat f LEFT JOIN FETCH f.lineEquipmentFormatDivisions
WHERE f.id = 1