用于加载惰性列表的 Hibernate Lazy Initialization Exception
Hibernate Lazy Initialization Exception for loading lazy list
我有这两个实体
@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.
我无法弄清楚为什么会出现此错误?为什么会出现此错误,我该如何解决?
我首先假设你想要你的collection延迟加载。
Hibernate 的 session 可以在很多上下文中关闭,一旦 session 关闭,它将无法获取任何延迟加载的 collection。
一般来说,Hibernate 非常善于在 web 应用程序上下文中保持 sessions 为 HTTP 线程的生命周期打开(Spring 的“在视图中打开 session”)。 session 可能被关闭的原因包括 object 从一个线程移交给另一个线程,或者 object 被缓存然后被另一个线程访问。
但如果您的代码是 运行 在工作或 non-web 应用程序上下文中,则可能会更加困难。
修复
1.创建一个存储库方法以显式获取 collection
使用 @Query
和 join fetch
,添加明确 eager-loads collection.
的存储库方法
2。获取 object.
后在 collection 上调用 .toString()
这是我以前在现实世界中看到很多人使用过的一个令人讨厌的技巧。基本上,在缓存 object 或将其交给执行程序或其他线程将访问它的某个地方之前,调用 collection 上的 .toString() 来加载它。通常留下评论解释原因。
3。将 @Transactional 添加到同时获取数据和访问 collection
的方法
除了让 session 保持活动状态(例如,数据库操作同时成功和失败)之外,这还有很多含义,但可以快速修复以保持 session 活动状态,例如作业方法.
希望对您有所帮助。
我有这两个实体
@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.
我无法弄清楚为什么会出现此错误?为什么会出现此错误,我该如何解决?
我首先假设你想要你的collection延迟加载。
Hibernate 的 session 可以在很多上下文中关闭,一旦 session 关闭,它将无法获取任何延迟加载的 collection。
一般来说,Hibernate 非常善于在 web 应用程序上下文中保持 sessions 为 HTTP 线程的生命周期打开(Spring 的“在视图中打开 session”)。 session 可能被关闭的原因包括 object 从一个线程移交给另一个线程,或者 object 被缓存然后被另一个线程访问。
但如果您的代码是 运行 在工作或 non-web 应用程序上下文中,则可能会更加困难。
修复
1.创建一个存储库方法以显式获取 collection
使用 @Query
和 join fetch
,添加明确 eager-loads collection.
2。获取 object.
后在 collection 上调用 .toString()这是我以前在现实世界中看到很多人使用过的一个令人讨厌的技巧。基本上,在缓存 object 或将其交给执行程序或其他线程将访问它的某个地方之前,调用 collection 上的 .toString() 来加载它。通常留下评论解释原因。
3。将 @Transactional 添加到同时获取数据和访问 collection
的方法除了让 session 保持活动状态(例如,数据库操作同时成功和失败)之外,这还有很多含义,但可以快速修复以保持 session 活动状态,例如作业方法.
希望对您有所帮助。