4 Replies Latest reply on Aug 21, 2007 8:25 AM by pmuir

    Page refresh when hitting F5

    enrico256

      We have a simple CRUD application based on Seam 1.2.1 that manages items. These are presented in a list (DataModel) from which they can be viewed and modified. When an item is updated by a user it should be possible for everyone watching the very same data to view the changes by reloading the page (hitting F5). Unfortunately, the old data is displayed. We tried disabling second level caching without success.

      Does anybody have a hint?

      Thanks in advance, Enrico

        • 1. Re: Page refresh when hitting F5
          pmuir

          Post code.

          • 2. Re: Page refresh when hitting F5
            enrico256

            Here is an extract of the code:

            home.xhtml shows the list of items

            <rich:dataTable id="items" value="#{items}" var="_item" >
             <rich:column>
             <s:link action="#{itemFinder.selectItem}" value="#{_item.id}"/>
             </rich:column>
             <rich:column>
             <h:outputText value="#{_item.title}" />
             </rich:column>
             <rich:column>
             <h:outputText value="#{_item.date}" >
             <f:convertDateTime pattern="dd.MM.yyyy" />
             </h:outputText>
             </rich:column>
             ....
            </rich:dataTable>

            ItemFinderAction manages the data model and the selected item:
            @Stateful
            @Name("itemFinder")
            @Scope(ScopeType.SESSION)
            public class ItemFinderAction implements ItemFinder {
            
             @PersistenceContext
             EntityManager em;
            
             @DataModel("items")
             List<Item> items;
            
             @DataModelSelection("items")
             @Out(required=false)
             Item item;
            
             @Factory("items")
             public void refresh() {
             items = em.createQuery("from Item i order by i.date asc").getResultList();
             }
            
             @Begin
             public String selectItem() {
             return "view_item";
             }
            
             @Remove @Destroy
             public void destroy() {
             }
            }

            Upon item selection, the item is viewed in viewitem.xhtml:
            <h:form id="viewItem">
             <h:panelGrid columns="2">
             <h:outputText value="Title"/>
             <h:outputText value="#{item.title}"/>
             <h:outputText value="Date"/>
             <h:outputText value="#{item.date}"/>
             ...
             </h:panelGrid>
             ...
             <s:link action="#{itemEditor.beginUpdate}"value="Update" />
             ....
            </h:form>
            

            ItemEditorAction manages the creation and update of items:
            @Stateful
            @Name("itemEditor")
            public class ItemEditorAction implements ItemEditor {
            
             @In(required=false)
             User user;
            
             @In(required=false) @Out(required=false)
             Item item;
            
             @PersistenceContext
             EntityManager em;
            
             @Begin
             public String beginRegister() {
             item = new Item();
             item.setDate(new Date());
             item.setNew(true);
             return "edit_item";
             }
            
             public String endRegister() {
             em.persist(item);
             refreshItems();
             return "success";
             }
            
             public String beginUpdate() {
             item.setNew(false);
             return "edit_item";
             }
            
             public String endUpdate() {
             em.merge(item);
             refreshItems();
             return "success";
             }
            
             @Remove @Destroy
             public void destroy() {
             }
            
             private void refreshItems() {
             Events.instance().raiseEvent("loadItems");
             }
            }

            loadItems is defined in compontents.xml as
            <event type="loadItems">
             <action expression="#{itemFinder.refresh}"/>
             </event>

            Creation and update is done through the following xhtml page:
            <h:form id="register">
             <rich:panel>
             <f:facet name="header">
             <h:panelGroup>
             <h:outputText value="New item" rendered="#{item.new}"/>
             <h:outputText value="Item #{item.id}" rendered="#{!item.new}"/>
             </h:panelGroup>
             </f:facet>
             <h:panelGrid columns="2">
             <h:outputText value="Title" />
             <h:inputText value="#{item.title}" size="100" maxlength="100"/>
            ...
             </h:panelGrid>
             <h:commandButton action="#{itemEditor.endRegister}" value="Save" rendered="#{item.new}"/>
             <h:commandButton action="#{itemEditor.endUpdate}" value="Save" rendered="#{!item.new}" />
             <s:button action="/home.xhtml" value="Cancel" rendered="#{item.new}" propagation="end" />
             <s:button action="/viewitem.xhtml" value="Cancel" rendered="#{!item.new}" />
             </rich:panel>
            </h:form>
            

            Item is defined as
            @Entity
            @Name("item")
            @Table(name="ITEMS")
            public class Item implements Serializable {
             private static final long serialVersionUID = 1L;
             private long id = 0L;
             private String title;
             private Date date;
             private boolean new;
             //... setters and getters
             @Transient boolean isNew() {
             return new;
             }
            }


            • 3. Re: Page refresh when hitting F5
              enrico256

              Pete, is this code shedding any light on the problem?

              Thanks, Enrico

              • 4. Re: Page refresh when hitting F5
                pmuir

                Sorry about the delay. An event is raised on the component returned from Contexts.lookupInStatefulContexts(), i.e. in this case the method in the current users sessions. It doesn't touch the ones outside that context.

                You could put it in application scope, or just redesign your scope usage based on considering what delay you can accept in that list being updated.