2010-09-06 78 views
1

我有實體:帖子,用戶,評論有雙向關係:EntityManager不從數據庫中提取?

--------- 1  * --------- 
| Post | <--------> |Comment| 
---------   --------- 

--------- 1  * --------- 
| User | <--------> |Comment| 
---------   --------- 

我有簡單的網頁,其中顯示一個帖子及其所有評論和誰寫他們的用戶。 在底部我有簡單的textarea當登錄用戶可以發表評論。當提交被單擊時,將調用從backing bean調用的saveComment方法。現在我鍵入評論點擊提交操作saveComment導航到同一頁面。 saveComment看起來是這樣的:

String username = getLoginName(); 
if(username != null) 
{ 
    User u = userBean.getUser(username); 
    post = postBean.getPost(post.getId()); 
    comment.setPost(post); 
    comment.setUser(u); 
    commentBean.updateComment(comment); 
    post = postBean.getPost(post.getId()); 
} 
return "viewpost?faces-redirect=true"; 

viewpost看起來是這樣的:

<ui:define name="content"> 
    <h:outputText value="#{postController.post.title}"/> 
    <br/> 
    <h:outputText value="#{postController.post.body}"/> 
    <br/> 
    <h:dataTable value="#{postController.post.comments}" var="item"> 
     <h:column> 
      <h:outputText value="#{item.body}"/> 
      <br/> 
      <h:outputText value="#{item.user.username}"/> 
      <br/> 
     </h:column> 
    </h:dataTable> 
    <h:form rendered="#{postController.loggedIn}"> 
    <h:inputTextarea value="#{postController.comment.body}"/> 
    <h:commandButton value="Submit" action="#{postController.saveComment}"/> 
    </h:form> 
</ui:define> 

然而,當我點擊提交評論保存到數據庫中,但它不是渲染。不是post = postBean.getPost(post.getId())這基本上是return em.find(Post.class, id)應該重新加載post,所以應該有新的評論?

還有支持bean的viewPost動作,它執行相同的操作post = postBean.getPost(post.getId()),但似乎又沒有從數據庫加載數據。我從數據庫中刪除了評論,但他們仍然列在視圖頁面中。

回答

2

你不應該打的數據庫(與EntityManager#refresh()EntityManager.find()不會碰到數據庫後話了實例在持久化上下文已經加載),如果你設置適當的雙向關聯。

問題是,你沒有和你的對象圖在添加註釋後被破壞,因此需要從數據庫重新加載帖子(這實際上是一個真正的錯誤的解決方法)。

基本上,你的模式是這樣的:

+-------+ 1  * +-------+ *  1 +-------+ 
| Post | <--------> |Comment| <--------> | User | 
+-------+   +-------+   +-------+ 

所以,你需要正確設置所有的雙向關聯的兩側添加註釋時:

String username = getLoginName(); 
if(username != null) 
{ 
    User u = userBean.getUser(username); 
    post = postBean.getPost(post.getId()); 

    post.getComments().add(comment); 
    comment.setPost(post); 

    u.getComments().add(comment); 
    comment.setUser(u); 

    commentBean.updateComment(comment); 

    //post = postBean.getPost(post.getId()); // you should not have to do this 
} 
return "viewpost?faces-redirect=true"; 

「設置兩側雙向關聯的鏈接「通常以輔助方法在實體上完成,例如在Post中:

@Entitysamples 
public class Post { 
    ... 
    public void addToComments(Comment comment) { 
     this.comments.add(comment); 
     comment.setPost(this); 
    } 
} 

這不易出錯,更易於使用,更易於閱讀。

無論如何,關鍵在於設置關聯的雙方,您不應該強制從數據庫重新加載以「修復」您的對象圖。

0

帖子可以被緩存。什麼是你的文章@ID?如果在緩存中存在具有指定ID的Post,則它不是從數據庫中取出而是從緩存中取出。嘗試禁用緩存。

我不知道,但我想

return "viewpost?faces-redirect=true"; 

將無法​​正常工作。 JSF導航處理程序接收此字符串,並檢查它是否在faces-config.xml中配置。如果它不存在,它將附加默認擴展名(可能是.xhtml),並嘗試重定向到這樣的頁面。所以它可能會嘗試將您重定向到viewpost?faces-redirect=true.xhtml,這顯然不存在。

+0

'viewpost?faces-redirect = true'的作品。 – l245c4l 2010-09-06 16:55:53

+0

這是JSF 2.0的一部分。隱式導航。沒有faces-config了。 '?faces-redirect = true'取代舊式導航案例中的''。 – BalusC 2010-09-06 17:21:44

+0

如何禁用緩存? – l245c4l 2010-09-06 22:16:50