我有实体:帖子,用户,评论双向关系:
--------- 1 * ---------
| Post | <--------> |Comment|
--------- ---------
--------- 1 * ---------
| User | <--------> |Comment|
--------- ---------
我有一个简单的页面,显示单个帖子及其所有评论和编写它们的用户。 在底部我有简单的textarea登录用户可以发表评论。单击提交时,将调用方法saveComment from backing bean。现在我输入注释点击提交操作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())
的{{1}}不应该重新加载return em.find(Post.class, id)
,以便新评论可用吗?
在支持bean中也有viewPost操作执行相同的post
,但同样看起来数据没有从数据库加载。我从数据库中删除了评论,但它们仍然列在了viewpost页面中。
答案 0 :(得分:2)
如果适当地设置双向关联,则不应该访问数据库(使用EntityManager#refresh()
,如果已在持久性上下文中加载了post实例,则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);
}
}
这不易出错,易于使用,更易于阅读。
无论如何,关键是要设置关联的两面,你不必强制从数据库重新加载来“修复”你的对象图。
答案 1 :(得分:0)
可以缓存帖子。你帖子里的@ID是什么?如果在缓存中存在具有指定标识的Post,则从缓存而不是从数据库获取。尝试禁用缓存。
我不确定,但我认为
return "viewpost?faces-redirect=true";
不起作用。 JSF导航处理程序接受此字符串,并检查它是否在faces-config.xml
中配置。如果它不存在,它会附加默认扩展名(可能是.xhtml)并尝试重定向到此类页面。所以它可能会尝试将您重定向到显然不存在的viewpost?faces-redirect=true.xhtml
。