【问题标题】:Hibernate Object Eagerly Loads Lazy CollectionHibernate 对象急切地加载惰性集合
【发布时间】:2015-05-22 17:58:42
【问题描述】:

我有一个休眠实体对象调用项目,它有两个集合,称为注释和消息,如下所示:

@Entity
@Table(name = "project")
public class Project {
    ...
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
    private List<Note> notes;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "project")
    private List<Message> messages;
    ...
}

但由于某种原因,在我获取项目的测试方法中,注释和消息已经加载,我的测试验证了这一点:

@Test
public void testLoadProjectNotes() {
    Project project = projectDao.getProjectById(41);
    assertNotNull(project.getNotes().get(0));

}

我认为问题可能是我正在获取笔记并导致休眠将它们加载到项目中。但是,在我执行该语句之前,调试器会在我得到注释之前显示项目中的注释。

下面是通过id获取项目的方法:

public Project getProjectById(long id) {
    Criteria criteria = new SmartCriteria(getSession().createCriteria(Project.class));
    criteria.add(Restrictions.eq("id", id));
    return (Project) criteria.uniqueResult();
}

因此,在通过 id 获取项目的方法中,我没有得到注释和消息的结果。

如何确保我想要延迟加载的集合被延迟加载?

【问题讨论】:

  • 你能在这一行调试吗project.getNotes().get(0)。当你调用它时,hibernate 将发送一个加载笔记的请求。所以如果你调试你可以看到在调用getnotes()之前没有任何值。
  • 就是这样,在我执行project.getNotes().get(0)之前有一个值。
  • 来自 javadoc:“LAZY 策略是对持久性提供程序运行时的提示,即在首次访问数据时应延迟获取数据。允许实现急切地获取 LAZY 策略提示具有的数据已指定。”
  • @sodik ...并且已指定。除此之外,@OneToMany@ManyToMany 的默认设置是延迟加载。
  • 那么,检索这些对象的 JPQL 查询是什么?如果您将注释/消息指定为获取连接,那么您将显式覆盖延迟初始化。

标签: java spring hibernate collections lazy-loading


【解决方案1】:

只要调用 getter,就会初始化一个延迟加载的集合。因此,如果集合是延迟加载的,那么该语句迄今为止无法检测。如果要检查,请使用方法Hibernate.isInitialized(project.getNotes())

【讨论】:

  • 对,我在调用getter之前检查过,笔记已经在项目中了。
  • 你是怎么查到的?
  • 调试器,见图片添加到原始问题
【解决方案2】:

所以我想通了,当我打开项目变量上的显示并单击注释或消息时,eclipse 会在项目上调用 getNotes 和 getMessages,从而从数据库中动态加载注释和消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多