下面的代码触发了一个线程“main”中的异常 org.hibernate.LazyInitializationException:未能延迟初始化角色集合:com.model.entity.WorkflowProcessEntity.workstations,没有 session 或 session 已关闭
错误。所以我用 @Transactional
将方法包装在一个服务类中,但它仍然会抛出错误。
WorkstationService workstationService = (WorkstationService) ApplicationContextProvider.getApplicationContext().getBean("workstationService");
for (WorkstationEntity workstationEntity : workstationService.getWorkstations(getEntity())) {
registerWorkstation(new ImpositionWorkstation(workstationEntity));
}
WorkstationService.java
@Transactional(readOnly = true)
public Collection<WorkstationEntity> getWorkstations(WorkflowProcessEntity workflowProcessEntity) {
return workflowProcessEntity.getWorkstations();
}
WorkflowProcessEntity.java
@OneToMany(mappedBy = "workflowProcess")
@JsonIgnore
public Collection<WorkstationEntity> getWorkstations() {
return workstations;
}
如何正确查询这种关系?
最佳答案
你的代码有两个问题。
首先,您将一个分离的实体传递给事务服务,并希望该实体自动附加。事实并非如此,分离的实体是分离的,无论您是否在事务中,尝试从分离的实体加载一些惰性属性都会导致异常。要加载它,您必须通过 ID 从 session 中重新加载实体,然后从该附加实体加载惰性集合。
其次,您假设从实体获取集合并加载它。事实也并非如此。集合被实现为延迟加载代理,获取集合并返回它只不过是获取代理(unitilialized)并返回它。只有在调用集合上的方法时,代理才会自行初始化。例如,在遍历集合时。这是在交易之外完成的。堆栈跟踪(如果您提供的话)可能会确认异常 io 不是从服务内部抛出的,而是从服务外部的迭代中抛出的。
关于spring - 在事务内部时无法延迟初始化集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17662634/