Latte
Latte

Reputation: 1

How to display menu from database in a JSF template

I want to display menu in JSF template. Every user of my application has different menu and the menu is stored in database. Here is my code,

MenuBean.java

public List<Menuitem> getUserMenu() {
    List<Menuitem> menuitems = (List<Menuitem>) em.createQuery("_____________").setParameter("_______", _______).getResultList();
    return menuitems;
}

pageTemplate.xhtml

<div class="container">
    <div id="navigation">
        <ul>
            <ui:repeat var="_item" value="#{menuitemBean.userMenu}">
                <li><h:outputLink value="#{_item.url}">
                        <h:outputText value="#{_item.name}" />
                    </h:outputLink></li>
            </ui:repeat>
        </ul>
    </div>

    <div id="content">
        <h1>
            <ui:insert name="header" />
        </h1>
        <h2>
            <ui:insert name="subheader" />
        </h2>

        <ui:insert name="main" />
    </div>
</div>

Problem is each time I navigate to a new page (.xhtml file) which is using the same template (pageTemplate.xhtml) the menu is loading all over again.

How can I load the menu only once per user.

Upvotes: 0

Views: 1109

Answers (2)

Elias Dorneles
Elias Dorneles

Reputation: 23886

You should NOT put logic accessing the database in a getter method, because they are often called more than once in the same request.

To load your menu once for each user, put the property in a @SessionScoped backing bean and then initialize it in a @PostConstruct annotated method:

@SessionScoped
public SomeBean {
    private List<Menuitem> menuItems;

    @PostConstruct
    public void init() {
        menuItems = (List<Menuitem>) em.createQuery("_____________")
                           .setParameter("_______", _______).getResultList();
    }
    // getter and setter for menuItems
}

As the bean is in the session scope, it will exist as one instance for each user session in your application.

Note that I assumed you are using JSF 2, because you tagged the question as .

Upvotes: 2

Romain Linsolas
Romain Linsolas

Reputation: 81657

If the menu is dependent on the user, it would be better to create a bean with a scope session that will store the content of this menu. This way, once the menu is initialized the first time, it will not be re-initialized. Your code will look like that:

public class MySessionBean ... {

    private List<Menuitem> menuItems = null;

    public List<Menuitem> getUserMenu() {
        if (menuItems == null) {
            // Initialize the menu items.
            menuItems = ...;
        }
        return menuitems;
    }

Note that you can also initialize the menuItems objects in the constructor, or in a post-construct method (i.e. a method called just after the bean is instantiated).

An important thing also : do not put database access code in your beans (your em.createQuery(...)). Move that on service / DAO layers, and let the bean call the service to retrieve the information needed to build the menu items.

Upvotes: 4

Related Questions