简体   繁体   English

如何在 Java EE Web 应用程序中使用延迟实体加载?

[英]How to use Lazy Entity Loading in a Java EE Web Application?

In my Web Application I load many Entities, to display them in a table.在我的 Web 应用程序中,我加载了许多实体,以将它们显示在表格中。 I can click on each tablerow to get the 'detailed information' regarding the specific entity.我可以单击每个表格行以获取有关特定实体的“详细信息”。

To me it was obvious to not load the 'detailed information' for the tableview, but only when someone wants to see it (clicks a row).对我来说,很明显不加载表格视图的“详细信息”,但只有当有人想要查看它时(单击一行)。

Just setting (fetch = FetchType.LAZY) for these fields didn't work because the entities get detached after fetching and in my WebApp there will be nulls.只是为这些字段设置(fetch = FetchType.LAZY)不起作用,因为实体在获取后会分离,并且在我的 WebApp 中会有空值。

Okay, so the next thing I did was to prevent the detaching by putting my fetch-operations into a StatefulSessionBean with an extended PersistenceContext.好的,接下来我要做的是通过将我的获取操作放入具有扩展 PersistenceContext 的 StatefulSessionBean 中来防止分离。

@PersistenceContext(unitName="unitname", type=PersistenceContextType.EXTENDED) private EntityManager em; @PersistenceContext(unitName="unitname", type=PersistenceContextType.EXTENDED) private EntityManager em;

This works but produces strange sideeffects too (most notably ConcurrentAccessExceptions on some page reloads, which I could fix by setting some openjpa-property) Servlets need their own fetching-ejbs since they don't team up with SFSBs.这可行,但也会产生奇怪的副作用(最明显的是某些页面重新加载时的ConcurrentAccessExceptions ,我可以通过设置一些 openjpa-property 来解决) Servlets 需要自己的 fetching-ejb,因为它们不与 SFSB 合作。 Atm most things seem to work okay but I'm expecting the s**t to hit the fan soon. Atm 大多数事情似乎都可以正常工作,但我希望该 ** t 很快就会击中风扇。

My question is if I'm on the wrong track.我的问题是我是否走错了路。 This all seems a little awkward to me.这一切对我来说似乎有点尴尬。 Using a stateful bean when there is no real conversation and a user can leave at any time without triggering some @Remove-Method.当没有真正的对话并且用户可以随时离开而不触发某些@Remove-Method 时使用有状态bean。 Having to close resources on Timeout when the user is long gone, resulting in many open-unused SFSBs.当用户早已离开时,必须在 Timeout 上关闭资源,从而导致许多打开未使用的 SFSB。

LazyLoading in general is a quite simple thing but in the Java EE Environment I don't get how to do it. LazyLoading 通常是一件非常简单的事情,但在 Java EE 环境中,我不知道该怎么做。 What is the best practice?最佳做法是什么?

Thank you.谢谢你。

UPDATE更新

this is how I manually fetch the fields now这就是我现在手动获取字段的方式

@SuppressWarnings("unchecked")
public <T extends BasicEntity> T loadLazyField(T entity, String field) throws NoSuchFieldException {
    if (!typeHasField(entity.getClass(), field)) {
        throw new NoSuchFieldException(entity.getClass().getSimpleName() + " has no field called " + field);
    }

    String queryString = String.format("SELECT x FROM %s x WHERE x = :entity LEFT JOIN FETCH x.%s", entity.getClass()
            .getSimpleName(), entity, field);
    Query q = em.createQuery(queryString);
    q.setParameter("entity", entity);
    return (T) q.getSingleResult();
}

@SuppressWarnings("unchecked")
public <T extends BasicEntity> T loadLazyFields(T entity, String[] fields) throws NoSuchFieldException {
    String queryString = String.format("SELECT x FROM %s x WHERE x = :entity", entity.getClass().getSimpleName());

    for (String field : fields) {
        if (!typeHasField(entity.getClass(), field)) {
            throw new NoSuchFieldException(entity.getClass().getSimpleName() + " has no field called " + field);
        }
        queryString += String.format(" LEFT JOIN FETCH x.%s", field);
    }
    Query q = em.createQuery(queryString);
    q.setParameter("entity", entity);
    return (T) q.getSingleResult();

}

private boolean typeHasField(Class<?> type, String field) {
    try {
        type.getDeclaredField(field);
        return true;
    } catch (NoSuchFieldException e) {
        return false;
    }
}

You need a design pattern called "Open Session in View" keeping the persistence session open in the page rendering phase.您需要一个名为“在视图中打开 Session”的设计模式,在页面渲染阶段保持持久性 session 打开。 This feature is provided by Integration Frameworks like Seam.此功能由 Seam 等集成框架提供。

I'm not sure if this is supported by JSF2, since many features from Seam2 moved to JavaEE6.我不确定 JSF2 是否支持这一点,因为 Seam2 的许多特性都移到了 JavaEE6。 Anyhow, you should take a look for Seam (although it's hard to get something running with Seam3).无论如何,您应该看看 Seam(尽管使用 Seam3 很难运行某些东西)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM