一尘不染

如何测试延迟加载的JPA集合是否已初始化?

hibernate

我有一个从外部代码获取JPA实体的服务。在此服务中,我想遍历一个延迟加载的集合(该实体的属性),以查看客户端是否相对于数据库中的当前版本向其添加了一些内容。

但是,客户端可能从未接触过该集合,因此仍未初始化。这导致众所周知

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.SomeEntity.

当然,如果客户从未接触过该系列,则我的服务不必检查它是否有可能更改。事实是,我似乎找不到找到测试集合是否已初始化的方法。我想我可以呼吁size()它,如果它抛出,LazyInitializationException我会知道的,但是我试图不依赖于这种模式。

isInitialized()什么办法吗?


阅读 403

收藏
2020-06-20

共1个答案

一尘不染

您正在使用JPA2吗?

PersistenceUnitUtil 有两种方法可用于确定实体的加载状态。

例如,组织和用户之间存在双向的OneToMany / ManyToOne关系。

public void test() {
    EntityManager em = entityManagerFactory.createEntityManager();
    PersistenceUnitUtil unitUtil =
        em.getEntityManagerFactory().getPersistenceUnitUtil();

    em.getTransaction().begin();
    Organization org = em.find(Organization.class, 1);
    em.getTransaction().commit();

    Assert.assertTrue(unitUtil.isLoaded(org));
    // users is a field (Set of User) defined in Organization entity
    Assert.assertFalse(unitUtil.isLoaded(org, "users"));

    initializeCollection(org.getUsers());
    Assert.assertTrue(unitUtil.isLoaded(org, "users"));
    for(User user : org.getUsers()) {
        Assert.assertTrue(unitUtil.isLoaded(user));
        Assert.assertTrue(unitUtil.isLoaded(user.getOrganization()));
    }
}

private void initializeCollection(Collection<?> collection) {
    // works with Hibernate EM 3.6.1-SNAPSHOT
    if(collection == null) {
        return;
    }
    collection.iterator().hasNext();
}
2020-06-20