Hibernate对象怎样主动加载延迟集合

3

enter image description here我有一个名为project的hibernate实体对象,它包含两个集合:notes和messages。

@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));

我认为问题可能在于我获取了笔记并导致Hibernate将它们加载到项目中。不过,在执行该语句之前,调试器显示在获取笔记之前就已经将其加载到项目中。

以下是按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() 之前没有任何值。 - Viswanath Lekshmanan
这就是问题所在,执行project.getNotes().get(0)之前存在一个值。 - j will
从Javadoc中:“LAZY策略是对持久性提供程序运行时的提示,即在首次访问数据时应该懒惰地获取数据。实现允许急切地获取已指定LAZY策略提示的数据。” - sodik
@sodik...并且它已经被指定。此外,@OneToMany@ManyToMany的默认设置是进行延迟加载。 - Powerlord
那么,你的JPQL查询是什么,能够检索到这些对象呢?如果你将notes/messages指定为一次性加载(join),那么你就明确地覆盖了延迟初始化。 - Powerlord
2个回答

8
只要调用getter方法,就会初始化延迟加载的集合。因此,这个语句绝对无法用于检测集合是否是延迟加载的。如果你想检查这一点,使用方法Hibernate.isInitialized(project.getNotes())

没错,我在 getter 被调用之前进行了检查,笔记已经存在于项目中了。 - j will
你是如何检查的? - dunni
调试器,请参见原问题中添加的图片。 - j will

0
所以我弄明白了,当我打开项目变量的显示并单击备注或消息时,Eclipse会调用项目上的getNotes和getMessages,并从数据库动态加载备注和消息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接