0

I have primefaces p:tree element. In my backing bean I have a field 'root' which holds all the tree structure. I populate this 'root' field in init method which is annotated with @PostConstruct annotation. When I perform some CRUD operation, like adding a new element to the tree and submit the form, the page is not updated with new information. The JSF bean is @ViewScoped. The thing is, that p:tree's getter gets called after page is refreshed, but I cannot put update logic in there as it is very expensive DB operation and getter gets called too many times in JSF lifecycle. The init method only gets called once and does not update the tree structure. Even if I make the bean @RequestScope, it does not fix the problem. The @PostConstruct method gets called first, then the database method addCategory() gets called and then the tree with old informtion is rendered. @RequestScope just makes everything slow, like selecting tree nodes in UI.. How can I solve this, preferably without ajax? I am using JSF 2.2 with Primefaces. I suppose this is not intended JSF behavior and something is wrong with my project's configuration maybe?

Bean:

@ManagedBean(name="menuBean")
@ViewScoped
public class MenuBean {

   private TreeNode root;
   private TreeNode selectedNode;
   private UiElement category = new CategoryElement();

   @PostConstruct
   public void init() {
      root = new DefaultTreeNode("root", null);
      List<UiElement> rootElements = menuElementDao.getRootElements();
      for (UiElement element : rootElements) {
         if (element.isActive() || admin) {
            createNodeWithChildren(element, root, admin);
         }
       }
    }

    public void addCategory() {
       if (selectedNode != null) {
          category.setParent((UiElement) selectedNode.getData());
       }
       menuElementDao.addElement(category);
       category.clear();
    }

    public void setRoot(TreeNode root) {
       this.root = root;
    }

    public TreeNode getRoot() {
       return root;
    }
}

Index.xhtml:

   <h:form id="categoryForm">
      <h:panelGrid id="categoryFormGrid" columns="2" style="border:1px solid               black" styleClass="controlVisibility">
         <h:outputLabel for="categoryName" value="Category name: "/>
         <h:inputText id="categoryName" value="#{menuBean.category.name}">
            <p:ajax/>
         </h:inputText>

         <h:commandButton value="Add Category" action="#{menuBean.addCategory()}"/>
         <h:outputText/>
    </h:panelGrid>
</h:form>

<h:form>
    <p:tree value="#{menuBean.root}" var="node" selectionMode="single" selection="#{menuBean.selectedNode}" dynamic="true">
        <p:ajax event="select" update="controlButtons"/>
        <p:ajax event="unselect" update="controlButtons"/>
        <p:treeNode>
            <h:outputText value="#{node.render()}"/>
        </p:treeNode>
    </p:tree>
</h:form>
eek
  • 37
  • 6
  • _"How can I solve this, preferably without ajax?"_ why? – Kukeltje Nov 09 '16 at 21:15
  • 1
    Well, I am building a simple demo app and it has to work with about 10,000 products, so it can get pretty slow. With ajax, it appears that nothing is happening when database operations are executing and I am lazy to add spinners.. I would just like to reload the page and see the refreshed data. But somehow it isn't working :/ – eek Nov 09 '16 at 21:24
  • Anyway, how could I do it with ajax? I suppose I add – eek Nov 09 '16 at 21:37
  • 10,000 products shouldn't be slow and reloading the page is slower than ajax. – ForguesR Nov 09 '16 at 22:23
  • Hmm, well it takes about 13 seconds for Hibernate to load 50 root items with about 200 children each from database. Do you think there is bottle neck somewhere? Hmm, I will try with regular sql without orm. Anyway, I still don't understand why JSF first refreshes the page and then calls dao method which is associated with commandButton's action.. – eek Nov 09 '16 at 22:55
  • _"Anyway, I still don't understand why JSF first refreshes the page and then calls dao method which is associated with commandButton's action.. "_ That is not normal behaviour. It is invisible what `update="controlButtons"` does, if that happens without using the database to, create a [mcve] – Kukeltje Nov 10 '16 at 10:43
  • You can try to add `partialSubmit="true" process="@this"` to ` – Holger Nov 11 '16 at 09:34
  • Possibly this is the answer: http://stackoverflow.com/questions/20251176/viewscoped-bean-recreated-on-every-postback-request-when-using-jsf-2-2 – Holger Nov 11 '16 at 09:40

0 Answers0