我有一个JPA设置,如果我不使用延迟加载,几乎将加载整个数据库。我还直接在模型上使用序列化,因此有时我需要初始化代理。
我只想在集合上使用延迟加载。一些单一的实体被急切地获取的事实很好。但无论我如何设置集合,我都没有得到代理集合,我总是得到满载的集合。
这是一些示例代码:
@Entity
public class Thread implements Externalizable {
@OneToMany(mappedBy = "parentThread", fetch = FetchType.LAZY)
public List<Reply> getReplies() {
return replies;
}
所以这里的问题是,当我检查调试器时,persistantBag-reply的回复总是用信息填充,并且是实际的Reply对象而不是我想要的空代理。
当我想要线程时,我使用entityManager.find(Thread.class,“ID”),所有这些集合总是完全加载,无论我是否有fetch = FetchType.LAZY。
据我了解,设置fetchtype lazy应该可以正常工作。此外,我希望在使用thread.getReplies()时加载实体,以便我可以序列化并将它们发送到客户端。我不知道getReplies是否可以与代理实体一起使用,因为我从来没有任何集合被延迟加载。
一方面我没有使用Intellij并用它来设置带有Hibernate的JPA。 我也问过一个类似的问题,我希望这个集合完全是空的,但我不确定这是否可行,而且我在那里问这个问题。
JPA Hibernate want lazy load to return empty collection
关于stackoverflow这个看似基本的问题,我还没有看到一个好的答案。如果问题是以教学方式回答的话,请回复一个链接,因为我是JPA / Hibernate的新手,也是真正的数据库。
非常感谢你!
答案 0 :(得分:3)
懒惰的集合不包含代理。该集合本身是一个懒惰的集合。这意味着当您从数据库中获取线程时,其回复列表将无法初始化。
调用getReplies()
只会返回此未初始化的列表。只有在列表本身上调用方法(如size()
或iterator()
)时,Hibernate才会通过执行加载线程所有回复状态的SQL查询来初始化列表。
使用调试器检查集合包含的内容并不是一个好主意,因为调试器通常会调用背后列表中的方法,这会导致列表自行初始化。您可以使用Hibernate.isInitialized(thread.getReplies())
方法检查集合是否已初始化。
关于您的另一个问题:Hibernate用于将数据库行映射到对象。如果某个帖子有回复,那么Hibernate永远不会告诉你它没有任何回复你的空列表。那将是一个严重的错误。如果您不想加载回复,请不要在回复列表中调用任何方法。