1

我有一个 JPA 设置,如果我不使用延迟加载,几乎整个数据库都会被加载。我也直接在模型上使用序列化,所以有时我需要初始化代理。

我只想对集合使用延迟加载。急切地获取一些单一实体的事实很好。但无论我如何尝试设置集合,我从来没有得到代理集合,我总是得到完全加载的集合。

这是一些示例代码:

@Entity
public class Thread implements Externalizable {
    @OneToMany(mappedBy = "parentThread", fetch = FetchType.LAZY)
    public List<Reply> getReplies() {
        return replies;
    }

所以这里的问题是,当我检查调试器时,回复的persistantBag-list 总是充满信息,并且是实际的回复对象,而不是我想要的空代理。

当我想要线程时,我使用 entityManager.find(Thread.class, "ID") ,并且无论我是否有 fetch = FetchType.LAZY ,所有像这样的集合总是完全加载。

据我了解,设置 fetchtype lazy 应该可以按我的意愿工作。此外,我希望在使用 thread.getReplies() 时加载实体,以便我可以序列化并将它们发送到客户端。我不知道 getReplies 是否可以与代理实体一起使用,因为我从未得到任何要延迟加载的集合。

另一方面,我使用 Intellij 并用它来设置带有 Hibernate 的 JPA。我还问了一个类似的问题,我希望集合完全为空,但我不确定这是否可能,因此我提出了这个问题。

JPA Hibernate 希望延迟加载返回空集合

关于stackoverflow这个看似基本的问题,我还没有看到一个好的答案。如果问题确实以教学方式回答,请仅回复链接,因为我是 JPA/Hibernate 和数据库的新手。

非常感谢您!

4

1 回答 1

4

惰性集合不包含代理。集合本身是一个延迟加载的集合。这意味着当您从数据库中获取一个线程时,它的回复列表不会被初始化。

调用getReplies()将简单地返回这个未初始化的列表。只有在调用列表本身的方法(如size()iterator())时,Hibernate 才会通过执行 SQL 查询加载线程所有回复的状态来初始化列表。

使用调试器检查集合包含的内容不是一个好主意,因为调试器通常会在您背后调用列表上的方法,这会导致列表自行初始化。您可以使用该方法检查集合是否已初始化Hibernate.isInitialized(thread.getReplies())

关于您的另一个问题:Hibernate 用于将数据库行映射到对象。如果一个线程有回复,Hibernate 永远不会通过返回一个空列表来告诉你它没有回复。那将是一个严重的错误。如果您不想加载回复,只需不要调用回复列表中的任何方法。

于 2013-04-30T07:58:59.737 回答