加载惰性列表的java Hibernate惰性初始化异常
我有这两个实体
@Entity
@Table(name = "CallSession")
public class CallSession implements Serializable {
private long id;
private List<CallParticipant> members;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@OneToMany(mappedBy = "callSession", fetch = FetchType.LAZY)
public List<CallParticipant> getMembers() {
return members;
}
public void setMembers(List<CallParticipant> members) {
this.members = members;
}
}
@Entity
@Table(name = "CallParticipant")
public class CallParticipant implements Serializable {
private long id;
private CallSession callSession;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@ManyToOne
public CallSession getCallSession() {
return callSession;
}
public void setCallSession(CallSession callSession) {
this.callSession = callSession;
}
}
但是当我调用callSession.getMembers()
方法时,
我得到一个例外:
Unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException' exception.
我弄不清楚为什么我会犯这个错误?为什么会出现此错误?如何修复此错误
# 1 楼答案
我将首先假设您希望您的集合被延迟加载
Hibernate的会话可以在很多上下文中关闭,一旦会话关闭,它将无法获取任何延迟加载的集合
通常,Hibernate非常擅长在web应用程序上下文中的HTTP线程生命周期中保持会话打开(Spring的“打开会话视图”)。会话可以关闭的原因包括对象从一个线程转移到另一个线程,或者对象被缓存,然后被另一个线程访问
但是,如果您的代码在作业或非web应用程序上下文中运行,则可能会更加困难
修复
1。创建存储库方法以显式获取集合
使用
@Query
和join fetch
,添加一个存储库方法,该方法显式地急于加载集合2。呼叫获取对象后对集合执行toString()强>
这是一个讨厌的黑客,我以前见过很多人在现实世界中使用。基本上,在缓存对象或将其交给执行者或其他线程访问对象的地方之前,调用。在集合上加载toString()以加载它。通常会留下解释原因的评论
3。将@Transactional添加到同时获取数据和访问集合的方法中
这除了使会话保持活动状态(例如,数据库操作同时成功和失败)外,还有许多其他含义,但在例如作业方法中,这可能是使会话保持活动状态的快速修复方法
希望这有帮助