簡體   English   中英

如何在 Java EE Web 應用程序中使用延遲實體加載?

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

在我的 Web 應用程序中,我加載了許多實體,以將它們顯示在表格中。 我可以單擊每個表格行以獲取有關特定實體的“詳細信息”。

對我來說,很明顯不加載表格視圖的“詳細信息”,但只有當有人想要查看它時(單擊一行)。

只是為這些字段設置(fetch = FetchType.LAZY)不起作用,因為實體在獲取后會分離,並且在我的 WebApp 中會有空值。

好的,接下來我要做的是通過將我的獲取操作放入具有擴展 PersistenceContext 的 StatefulSessionBean 中來防止分離。

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

這可行,但也會產生奇怪的副作用(最明顯的是某些頁面重新加載時的ConcurrentAccessExceptions ,我可以通過設置一些 openjpa-property 來解決) Servlets 需要自己的 fetching-ejb,因為它們不與 SFSB 合作。 Atm 大多數事情似乎都可以正常工作,但我希望該 ** t 很快就會擊中風扇。

我的問題是我是否走錯了路。 這一切對我來說似乎有點尷尬。 當沒有真正的對話並且用戶可以隨時離開而不觸發某些@Remove-Method 時使用有狀態bean。 當用戶早已離開時,必須在 Timeout 上關閉資源,從而導致許多打開未使用的 SFSB。

LazyLoading 通常是一件非常簡單的事情,但在 Java EE 環境中,我不知道該怎么做。 最佳做法是什么?

謝謝你。

更新

這就是我現在手動獲取字段的方式

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

您需要一個名為“在視圖中打開 Session”的設計模式,在頁面渲染階段保持持久性 session 打開。 此功能由 Seam 等集成框架提供。

我不確定 JSF2 是否支持這一點,因為 Seam2 的許多特性都移到了 JavaEE6。 無論如何,您應該看看 Seam(盡管使用 Seam3 很難運行某些東西)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM