Reputation: 1
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
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 java-ee-6.
Upvotes: 2
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