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

2022-08-31 16:57:58

我有一个从外部代码获取JPA实体的服务。在此服务中,我想循环访问一个延迟加载的集合,该集合是此实体的属性,以查看客户端是否已相对于 DB 中的当前版本向其添加了某些内容。

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

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

当然,如果客户端从未接触过集合,则我的服务不必检查它是否可能更改。问题是我似乎找不到一种方法来测试集合是否已初始化。我想我可以调用它,如果它投掷,我会知道,但我尽量不依赖于这样的模式。size()LazyInitializationException

在某个地方有某种方法吗?isInitialized()


答案 1

您使用的是 JPA2 吗?

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

例如,组织和用户之间存在双向的一对多/多对一关系。

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();
}

答案 2
org.hibernate.Hibernate.isInitialized(..)

据我所知,没有标准的JPA解决方案。但是,如果要实际初始化集合,则可以创建一个实用工具方法并对其进行迭代(只需一次迭代就足够了)。


推荐