用于加载惰性列表的 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

使用 @Queryjoin fetch,添加明确 eager-loads collection.

的存储库方法

2。获取 object.

后在 collection 上调用 .toString()

这是我以前在现实世界中看到很多人使用过的一个令人讨厌的技巧。基本上,在缓存 object 或将其交给执行程序或其他线程将访问它的某个地方之前,调用 collection 上的 .toString() 来加载它。通常留下评论解释原因。

3。将 @Transactional 添加到同时获取数据和访问 collection

的方法

除了让 session 保持活动状态(例如,数据库操作同时成功和失败)之外,这还有很多含义,但可以快速修复以保持 session 活动状态,例如作业方法.

希望对您有所帮助。