Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
初始化JPA2惰性关联的通用方法_Jpa_Jpa 2.0_Lazy Loading - Fatal编程技术网

初始化JPA2惰性关联的通用方法

初始化JPA2惰性关联的通用方法,jpa,jpa-2.0,lazy-loading,Jpa,Jpa 2.0,Lazy Loading,因此,手头的问题是初始化“未知”实体的惰性集合,只要这些集合至少是通过名称已知的。这是我在JSF+Primefaces中构建通用DataTable->RecordDetails迷你框架的更广泛工作的一部分。 因此,关联通常是惰性的,我需要加载它们的唯一时刻是当有人访问datatable中多条记录中的一条记录以查看/编辑它时。这里的问题是控制器是通用的,为此,我还使用了一个服务类来支持datatable的整个懒散加载和从details部分加载/保存记录。 到目前为止,我得到的是以下代码: publ

因此,手头的问题是初始化“未知”实体的惰性集合,只要这些集合至少是通过名称已知的。这是我在JSF+Primefaces中构建通用DataTable->RecordDetails迷你框架的更广泛工作的一部分。
因此,关联通常是惰性的,我需要加载它们的唯一时刻是当有人访问datatable中多条记录中的一条记录以查看/编辑它时。这里的问题是控制器是通用的,为此,我还使用了一个服务类来支持datatable的整个懒散加载和从details部分加载/保存记录。 到目前为止,我得到的是以下代码:

public <T> T loadWithDetails(T record, String... associationsToInitialize) {
    final PersistenceUnitUtil pu = em.getEntityManagerFactory().getPersistenceUnitUtil();
    record = (T) em.find(record.getClass(), pu.getIdentifier(record));
    for (String association : associationsToInitialize) {
        try {
            if (!pu.isLoaded(record, association)) {
                loadAssociation(record, association);
            }
        } catch (..... non significant) {
            e.printStackTrace(); // Nothing else to do
        }
    }
    return record;
}

private <T> void loadAssociation(T record, String associationName) throws IntrospectionException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
    BeanInfo info = Introspector.getBeanInfo(record.getClass(), Object.class);
    PropertyDescriptor[] props = info.getPropertyDescriptors();
    for (PropertyDescriptor pd : props) {
        if (pd.getName().equals(associationName)) {
            Method getter = pd.getReadMethod();
            ((Collection) getter.invoke(record)).size();
        }
    }
    throw new NoSuchFieldException(associationName);
}

但我不喜欢强迫我的POJO为此实现一些接口的想法。

使用反射解决方案,您将遭受此处详述的N+1效应:

您可以改为使用OpenSessionInView,您将受到N+1的影响,但不需要使用反射。如果使用此模式,您的事务将保持打开状态,直到事务结束,并且所有延迟关系都将毫无问题地加载


对于这种模式,您需要执行一个WebFilter来打开和关闭事务。

是的,N+1效应在这里不是问题。正如我在问题中所描述的,基本上只有当我需要“详细信息”视图时才会加载关联,所以它不是N个查询,而是每个关联多加载1个查询。此外,JPA标准不允许您检索多个一对多关联,因此这是必需的。现在,关于OpenSessionInView,问题不是这个。它是关于在加载时以通用方式加载关联。应该强制加载这些关联的东西。你说“JPA标准不允许你检索多个一对多关联”,你在哪里看到的?我执行了几个查询,比如:“从Person p join fetch p.cars join fetch p.pets中选择p”。
Object getId();
void loadAssociations();