2012-09-11 79 views
2

進出口使用JPA 1,Struts2.3.1,谷歌應用程序內,Enging 1.7.0訪問父實體

在我的漫畫我有下面的getter和setter屬性:

@ManyToOne(fetch=FetchType.LAZY, targetEntity=User.class) 
private User user = null; 

我JPA的查詢方法:

public Comics readComics(int random, String url){ 
    EntityManager em = EMF.get().createEntityManager(); 
    Comics comics = null; 

    try{ 
     Query q = em.createNamedQuery("Comics.getComics"); 
     q.setParameter("random", random); 
     q.setParameter("url", url); 
     comics = (Comics) q.getSingleResult(); 

    } catch(NoResultException ex){ 
     System.out.println("ERROR CATCHED: " + ex.getMessage()); 
     comics = null; 
    } finally{ 
     em.close(); 
    } 

    return comics; 
} 

在我看來,我有:

<s:property value="comics.user.userName"/> 

userName在這種情況下無法訪問,但是當實體管理器未關閉時,會顯示userName

什麼是正確的?可以刪除em.close()嗎?

=======================

使用BeanUtils.copyProperties 我也試過下面的代碼:

Comics emComics = (Comics) q.getSingleResult(); 
BeanUtils.copyProperties(comics, emComics); 
BeanUtils.copyProperties(comics.getUser(), emComics.getUser()); 

是它使用copyProperties的正確方法?刪除BeanUtils.copyProperties(comics.getUser(), emComics.getUser());將再次不顯示user

回答

2

刪除em.close()是不行的 - 如果你這樣做,你會最終連接泄漏。池中的所有連接都耗盡後,應用程序將停止工作。

簡單的修復是在調用em.close()之前確保jsp在初始化時需要的所有東西。

如果您正在使用Hibernate作爲提供者,那麼你如果您使用的是一些其他的供應商,你可以找等效的方法或只寫自己的功能,只是獲取可使用狀態,Hibernate.initialize()

public Comics readComics(int random, String url){ 
    EntityManager em = EMF.get().createEntityManager(); 
    Comics comics = null; 
    try{ 
     Query q = em.createNamedQuery("Comics.getComics"); 
     q.setParameter("random", random); 
     q.setParameter("url", url); 
     comics = (Comics) q.getSingleResult(); 

     Hibernate.initialize(comics.getUser()); 

    } catch(NoResultException ex){ 
     System.out.println("ERROR CATCHED: " + ex.getMessage()); 
     comics = null; 
    } finally{ 
     em.close(); 
    } 

    return comics; 
} 

觸發代理初始化的對象的屬性之一。

另一種方法是使用聯接提取修改查詢以在提取漫畫時提取用戶關聯。

正確的解決方案是使用Spring或提供解決方案的EJB來輕鬆處理實體管理器。您爲每個查詢打開一個新的entityManager的方法並不是最優的 - 它應該最好是每個事務或整個請求的一個entityManager。閱讀關於惰性初始化異常,OpenSessionInViewFilter等。

+0

謝謝。即時通訊使用datanucleus。我無法使用連接,因爲它在Google-App-Engine中被限制。 –

+0

是克隆對象好嗎? –

+0

是的,最好使用類似推土機或BeanUtils的東西。您可能遇到的一個問題是選擇需要複製哪些關係 - 您可能必須創建不同的類(VO DTO)才能返回與UI匹配的輸出,然後從域對象複製到這些類。 – gkamal