2010-09-06 3 views
1

У меня есть объекты: Post, Пользователь, комментарий с помощью двунаправленных отношений:EntityManager не получает из базы данных?

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

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

У меня есть простая страница, которая отображает одно сообщение и все его комментарии и пользователей, написавших их. Внизу у меня есть простая текстовая область, когда вошедший в систему пользователь может оставлять комментарии. При нажатии кнопки «Отправить» вызывается метод 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, чтобы новый комментарий был доступен?

Существует также действие viewPost в фоновом режиме, которое делает то же самое post = postBean.getPost(post.getId()), но опять же кажется, что данные не загружаются из базы данных. Я удалил комментарии из базы данных, но они все еще были указаны на странице viewpost.

ответ

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"; 

«Установка с обеих сторон ссылка двунаправленной ассоциации "обычно делается в вспомогательных методах на объектах, например, в Почте:

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

Это менее подверженная ошибкам, более простая в использовании и удобная для чтения.

В любом случае ключ состоит в том, чтобы установить обе стороны ваших ассоциаций, вам не нужно принудительно перезагружать базу данных, чтобы «исправить» граф объекта.

0

Сообщение может быть кэшировано. Что такое @ID в вашем сообщении? Если в кеше есть сообщение с указанным id, оно берется из кеша не из базы данных. Попробуйте отключить кеш.

Я не уверен, но я думаю, что

return "viewpost?faces-redirect=true"; 

не будет работать. Обработчик JSF-навигации принимает эту строку и проверяет, настроен ли он в faces-config.xml. Если его нет, он добавляет расширение по умолчанию (возможно, .xhtml) и пытается перенаправить на такую ​​страницу. Поэтому он, вероятно, пытается перенаправить вас на viewpost?faces-redirect=true.xhtml, который, очевидно, не существует.

+0

'viewpost? Faces-redirect = true' works. – l245c4l

+0

Это часть JSF 2.0. Неявная навигация. Нет лиц-config больше. '? Faces-redirect = true' заменяет' 'в случае с навигацией в старом стиле. – BalusC

+0

Как отключить кеш? – l245c4l

Смежные вопросы