1

JSF 2.0 (mojarra) application. I have a very trivial form for adding an item

<h:form>
    #{msg['add custom title']}:<br />
    <table>
        <tr>
            <td>#{msg['heaading']}:</td>
            <td><h:inputText value="#{titlesBean.title.heading}"></h:inputText></td>
        </tr>
        <tr>
                          ...
        </tr>
    </table>
    <h:commandButton action="#{titlesBean.addTitle}" value="#{msg['g.save']}" />
</h:form>

And then on the same page I have a list of all the items already added:

<h:dataTable id="manualTitlesForm" value="#{titlesBean.manualTitles}" var="title" border="1" cellspacing="0">
    <h:column>
        <f:facet name="header">#{msg['heaading']}</f:facet>
        #{title.heading}
    </h:column>
            ...
    <h:column>
        <f:facet name="header">#{msg['actions']}</f:facet>
        <h:form>
            <h:commandButton action="#{titlesBean.editManualTitle(title)}" value="#{msg['g.edit']}" />
            <h:commandButton action="#{titlesBean.deleteManualTitle(title.id)}" value="#{msg['g.delete']}" />
        </h:form>
    </h:column>
</h:dataTable>

The code in the bean code is super simple:

@Controller
@Scope(Scopes.REQUEST)
public class TitlesBean {

    private List<JTitle> manualTitles;


    @PostConstruct
    private void init() {
        this.manualTitles = titlesManager.getManualTitles();
    }

    public String addTitle() {
        title.setCreated(new Date());
        title.setManual(true);
        try {
            titlesManager.addTitle(title);
            title = new JTitle();// this is added, delete from the variable. only if no exception though !!!
            UserMessagesBean.addMessage("saved");
        } catch (Exception e) {
            UserMessagesBean.setValidationException(e.getMessage());//different exception added
        }
        return null;
    }

    public List<JTitle> getManualTitles() {
        return manualTitles;
    }
    }

Now the problem is that getManualTitles() is called as many times as the number of titles I have, which causes for example 12 calls to the DB, instead of one. Why is this happening is beyond my understanding. I can fix this with caching the manual titles in the bean. This is not my main problem.

The problem is that addTitle() is called AFTER getManualTitles(). In fact getManualTitles() is called for example 10 times, then addTitle(), then two more times the getManualTitles() method. This makes me think that this is some kind of parallel execution which causes my page to show only the 12 old records instead of 13. I have to reload the page, then 13 is shown.

UPDATED: now caches the list. Problem still not solved.

WHY? How can I fix this?

mist
  • 1,853
  • 2
  • 19
  • 33
  • 1
    possible duplicate of [Update backing bean in datatable from h:commandButton and JPA](http://stackoverflow.com/questions/7221758/update-backing-bean-in-datatable-from-hcommandbutton-and-jpa) – BalusC Sep 01 '11 at 11:41
  • This answers the question of multiple calls to the database, but how does that solve my main problem? – mist Sep 01 '11 at 13:15
  • 1
    This is covered by the code example in the answer as well. – BalusC Sep 01 '11 at 13:17
  • I have especially for this question updated my code with @PostConstruct. This does not solve my reload problem without redirect. – mist Sep 01 '11 at 13:34
  • I don't see the thing from the other example that should fix my problem with not seeing up-to-date data. – mist Sep 01 '11 at 13:37
  • That's definitely not a JSF problem. Perhaps you're using JPA and you simply didn't merge the entities into the current persistence context (which is by default namely threadlocal and in case of a webapplication thus requestbased). – BalusC Sep 01 '11 at 13:39
  • This is a problem my colleagues and I experienced more than once in different projects. It really doesn't make sense to be a JSF problem, but I have it nonetheless and I need a solution. – mist Sep 07 '11 at 12:56

1 Answers1

-1

This is a quick fix, but not a real solution. Redirect the result of addTitle():

Add the following to addTitle():

    ...
    FacesContext.getCurrentInstance().getExternalContext()
        .redirect("manualTitles.jsf");
    return null;
}
mist
  • 1,853
  • 2
  • 19
  • 33