Clear SessionScoped bean when refreshing page - jsf

I am using a Bean (MenuBean) to dynamically create a
<p:breadCrumb model="#{menuBean.model}" />
When transitioning through each page of my application, I push or pop pages from a "page stack", so as to adapt the breadCrumb of each page.
#ManagedBean
#SessionScoped
public class MenuBean implements Serializable {
private MenuModel model;
private int navIdx;
private ArrayList<String[]> pageStack;
#PostConstruct
public void init() {
pageStack = new ArrayList<>();
navIdx = 0;
String [] home = new String[2];
home[0] = "Home";
home[1] = "home.xhtml";
pageStack.add(home);
refreshModel();
}
private void refreshModel() {
model = new DefaultMenuModel();
int i = 0;
for(String[] s: pageStack) {
DefaultMenuItem index = new DefaultMenuItem();
index.setValue(s[0]);
index.setCommand("#{menuBean.navigate}");
index.setParam("index", String.valueOf(i++));
model.addElement(index);
}
}
private void push(String [] page) {
pageStack.add(page);
navIdx++;
refreshModel();
}
private String pop() {
pageStack.remove(navIdx--);
String[] prevPage = pageStack.get(navIdx);
refreshModel();
return prevPage[1];
}
}
In order to maintain this stack, my MenuBean is SessionScoped.
However, when I refresh the last page for example, the initial page is shown (since the url does not change) but the breadCrumb still displays the whole stack.
My question is: Is there a way to clear the MenuBean when the user leaves the page, or refreshes it?

One way you could refresh the bean is using remoteCommand with set auto run on true. So once you refresh the page remote commad will fire and call method in backing bean.
<!-- init bean on page load -->
<h:form id="initializePageDataForm">
<p:remoteCommand name="initializePageDataCommand" autoRun="true" action="#{MenuBean.init()}" />
</h:form>

This worked for me using JSF instead of Primefaces.
<!-- init bean on page load -->
<f:metadata>
<f:event type="preRenderView" listener="#{MenuBean.init() }" />
</f:metadata>

Related

open a menuitem page in a new tab in primefaces

I have a xhtml page with a session scoped backing bean. Now i have to open this page in a new tab with right click open link in new tab.
When this page opens the model class of the backing bean must be cleared.
I have used the following code:
<p:menuitem value="Details" action="#{beanMB.clearDetailModel()}"/>
backing bean code:
public void clearDetailModel()
{
memberModel=null;
......
return "/pages/member/MemberDetails.xhtml?faces-redirect=true";
}
The above code clears the session scoped model but it does not open the page in new tab.
Is there any method to open the page in new tab with the above code or is there any alternate way for the above problem?.Any help would be appreciated.
Thank you.
You can try this:
You need to put the following code in MemberDetails.xhtml page.
<f:metadata>
<f:event type="preRenderView" listener="#{beanMB.clearDetailModel}"/>
</f:metadata>
and use url in menuitem to open your page.
<p:menuitem value="Details" url="/pages/member/MemberDetails.xhtml" />
you need to modify your backing bean code as follows:
public void clearDetailModel()
{
if (isNewRequest()){
memberModel=null;
......
}
}
public boolean isNewRequest() {
final FacesContext fc = FacesContext.getCurrentInstance();
final boolean getMethod = ((HttpServletRequest) fc.getExternalContext().getRequest()).getMethod().equals("GET");
final boolean ajaxRequest = fc.getPartialViewContext().isAjaxRequest();
final boolean validationFailed = fc.isValidationFailed();
return getMethod && !ajaxRequest && !validationFailed;
}
Here method isNewRequest() checks if the request is new or not if this is not checked your method clearDetailModel() will be called each time new request is made.

Session Bean Data is lost after page reload or page change

I'm working on a JSF Project using a Wildfly 8 Server and jsf 2.2.
I've a web part with xhtml and beans + ejb part with models etc and a mysql database.
Part of Model (EJB part): Foo.java
String name = "";
Object Foo2 = new Foo2();
Part of Model (EJB part): Foo2.java
private static final long serialVersionUID = 1L;
String name = "";
Now I've input like this: input.xhtml
<f:metadata>
<f:event listener="#{ InputBean.init() }" type="preRenderView" />
</f:metadata>
<h:inputText
value="#{ InputBean.actualFoo.name }">
</h:inputText>
<h:selectOneMenu
value="#{InputBean.currentSelectedFoo2_ID}">
<f:selectItems value="#{InputBean.lhm_AllFoo2}" />
</h:selectOneMenu>
and a bean: InputBean.java
#SessionScoped
#ManagedBean(name = "InputBean")
public class InputBean implements Serializable
private static final long serialVersionUID = 1L;
private Long currentSelectedFoo2_ID;
private LinkedHashMap<String, Object> lhm_AllFoo2;
private Foo actualFoo;
public InputBean() {
lhm_AllPermissions = new LinkedHashMap<String, Object>();
actualFoo = new Foo();
}
public void init()
// Method of interface in EJB part which gives me all Foo2 to a list
List<Foo2> list_AllFoo2 = foo2Interface.getAllFoo2;
if ((list_AllFoo2 != null) && (list_AllFoo2.size() > 0)) {
for (Foo2 foo2 : list_AllBFoo2) {
lhm_AllFoo2.put(foo2.getName(), foo2.getId());
}
}
When I input data in the inputField and select data the selectonemenu and then reload the page (f5) or change to another page (of the same project) and go back the data in the input field is still avaiable but the selectonemenu is reseted to the default value.
I tried to debug the problem, but the data is already lost when the init is accessed, no setter of the bean is called before. The constructer isn't called too, so everything seems to be correct. The bean data which isn't linked to an input isn't lost too.
Is this a normal JSF problem and is there a way to solve that?

CommandLink not Working on a Lazy Loaded Primefaces Datascroller

I'm having an issue with lazy loading a Primefaces Datascroller component.
I have a jsf page that should display 10 events on page load. If the user wants to see more he/she can click the more button to load and display the 10 next events. For each of the event rows, there is a link that can be used to display the event's details.
<h:form id="mainForm" >
<p:dataScroller value="#{backing.lazyModel}" var="event" lazy="true" chunkSize="10" rowIndexVar="index">
#{event.name}
<p:commandLink class="view-trigger"
value="View Event Details"
actionListener="#{backing.initViewEventDetails(index, event)}"/>
<f:facet name="loader">
<p:outputPanel
visible="#{backing.lazyModel.rowCount gt 10}"
rendered="#{backing.lazyModel.rowCount gt 10}">
<p:commandLink value="More" />
</p:outputPanel>
</f:facet>
</p:dataScroller>
</h:form>
The initial search works fine, that is, when I click the view event details link, my backing bean is invoked and I see that the index and event received correspond to the row I clicked on.
However, once I load the next chunk, which consists of 1 extra event, the page displays 11 events but clicking a view event details link sends the proper index but does not send the proper event. For example, if I click on event at index 0, I get the event at index 10, if I click on event at index 1 my backing bean is not invoked.
It looks like the datascroller forgets about the last 10 events when I click on the more button but my lazy data model still remembers.
The backing bean:
#ManagedBean(name="backing")
#ViewScoped
public class DataScrollerBacking implements Serializable {
private static final long serialVersionUID = 4012320411042043677L;
private static final Logger LOGGER = Logger.getLogger(DataScrollerBacking.class);
#ManagedProperty("#{settings.dataSource}")
private String dataSource;
private WebEventDAO webEventDAO;
private LazyDataModel<Event> lazyModel;
#PostConstruct
public void init() {
webEventDAO = CommonDAOFactory.getInstance(dataSource).getWebEventDAO();
search();
}
public void search() {
DateTime start = new DateTime(2014, 1, 1, 0, 0 ,0);
final Date startDate = start.toDate();
final Date endDate = start.plus(Years.ONE.toPeriod()).minus(Seconds.ONE.toPeriod()).toDate();
lazyModel = new LazyDataModel<Event>() {
private static final long serialVersionUID = 1231902031619933635L;
private LinkedHashSet<Event> eventCache; // Ordered set of all retrieved events so far.
// I'm using a set because the load method is called twice on page load (any idea why???) and I don't want duplicates in my cache.
#Override
public List<Event> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
List<Event> events = new ArrayList<Event>(10);
try {
if(eventCache == null){
int count = webEventDAO.getSearchByPeriodRaceTypeAndRaceStatusForCompanyCount(Collections.singletonList(1), startDate, endDate, null, null);
this.setRowCount(count);
eventCache = new LinkedHashSet<Event>(count);
}
events = webEventDAO.searchByPeriodRaceTypeAndRaceStatusForCompany(Collections.singletonList(1), startDate, endDate, null, null, true, first, pageSize);
eventCache.addAll(events);
} catch (DAOException e) {
LOGGER.error("An error occurred while retrieving events.", e);
}
return events;
}
};
}
public void initViewEventDetails(Integer index, Event event){
LOGGER.info("index=" + index + " eventname=" + event.getName());
}
public String getDataSource() {
return dataSource;
}
public void setDataSource(String dataSource) {
this.dataSource = dataSource;
}
public LazyDataModel<Event> getLazyModel() {
return lazyModel;
}
public void setLazyModel(LazyDataModel<Event> lazyModel) {
this.lazyModel = lazyModel;
}}
Since the page displays the proper information and the index received is always valid, my current workaround is to go fetch the Event in the lazy data model by index.
However, I would like to understand why the received event is not the one I clicked on.
Am I doing something wrong or this is just how the scroller is implemented?
Running on Mojarra 2.2, Tomcat 7, Primefaces 5, Omnifaces 1.8
I found a good explanation about the behavior of request scope in this link http://www.theserverside.com/news/thread.tss?thread_id=44186
If you are using ManagedBeans in request scope, you get problems with
CommandLinks inside DataTables. DataTables are one thing I really like
about JSF, and CommandLinks often come in handy as well. But when you
put a CommandLink inside a DataTable, e. g., to select the entry of
the row in which the CommandLink is, you get bitten. That is, if you
want ManagedBeans with request scope. The action which should be
triggered by the CommandLink is never triggered, the page is simply
rendered again. The reason for this behaviour is that the DataTable
modifies the id of the CommandLink during renderering, but the
CommandLink does not know that it was rendered with a different id.
During the decoding of the request which was triggered by clicking the
CommandLink, the ComandLinkRenderer looks at a hidden form parameter.
If the value of that form parameter equals the id of the CommandLink,
an action is queued. If not, nothing is done. Since the DataTable
changes the ids, the value of the hidden form parameter does not match
the id of the CommandLink.
Based on above context, you need to change the scope annotations from #ViewScoped to
#SessionScope, and your problem will be solved automatically. It seems to be a better solution than write additional code, unless you need to keep the #ViewScopped
A workaround would be to use PrimeFaces remote command, passing arguments with rc([name: 'paramName', value: someParamValue]). These arguments should be available using #{param['paramName']} EL expression
Example:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:body>
<ui:composition>
<p:dataTable id="#{id}" widgetVar="#{id}"
value="#{requestCache.getLazy(id, () -> dataSource)}" var="rpo"
selectionMode="single" selection="#{selection}"
lazy="true" paginator="true" rows="#{pageSizeController.pageSize}"
pageLinks="10" paginatorPosition="top"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
currentPageReportTemplate="(#{label.Page} {currentPage} #{label.of} {totalPages}, #{label.Row} {startRecord} - {endRecord} #{label.of} {totalRecords})"
rowsPerPageTemplate="5 10 20 30 40 50 100"
scrollable="true" scrollHeight="#{empty scrollHeight ? 300 : scrollHeight}"
resizableColumns="true" emptyMessage="#{label.Table_is_empty}">
<p:column>
<h:outputText value="#{rpo.decreeSequence.code}" />
<p:commandLink id="displayAdditionalInfoCommandLink" type="link" style="float: right; text-decoration: none"
onclick="displayAdditionalInfo([{name: 'refundPaymentOrderId', value: #{rpo.id}}])"
title="#{label.Additional_information}">
<h:outputLabel for="displayAdditionalInfoCommandLink" styleClass="fa fa-info-circle"
onmouseover="jQuery(this).addClass('fa-lg').css('cursor', 'pointer')"
onmouseout="jQuery(this).removeClass('fa-lg')"/>
</p:commandLink>
</p:column>
</p:dataTable>
<p:remoteCommand name="displayAdditionalInfo" process="#this" update="#parent">
<f:setPropertyActionListener target="#{refundPaymentOrderCache.refundPaymentOrder}"
value="#{refundPaymentOrderRepo.find(requestCache.toLong(param['refundPaymentOrderId']))}" />
<f:actionListener binding="#{dialog.displayInputForm('RPO_ADDITIONAL_INFO')}" />
</p:remoteCommand>
</ui:composition>
</h:body>
</html>
I finally had time to spend on this issue and I found a workaround. It's a hack so maybe the proper solution would be to use a different component or create my own.
It seems like Primefaces DataScroller limitation that occurs when using the DataScroller with a LazyDataModel. It would seem that the component was not designed to do this.
To avoid this issue, I implemented my own lazy loading where the same list instance is returned in addition to the newly added elements.
Here is my previous example modified to implement this new lazy loading pattern:
The html page:
<h:form id="mainForm" >
<p:dataScroller value="#{backing.events}" var="event" rowIndexVar="index">
#{event.name}
<p:commandLink class="view-trigger"
value="View Event Details"
action="#{backing.initViewEventDetails(index, event)}"/>
<f:facet name="loader"><h:outputText value=""/></f:facet>
</p:dataScroller>
<p:commandLink value="More" process="#form" update="#form"
action="#{backing.loadMore()}"
visible="#{backing.totalCount gt backing.events.size()}"
rendered="#{backing.totalCount gt backing.events.size()}"/>
</h:form>
The DataScroller no longer has lazy="true", chunkSize="10", uses a list called events as the value and declares an empty loader facet (to avoid auto-load more when the bottom of the list is reached). I used a commandLink that calls backing.loadMore() and updates the form to replace the loader facet.
The backing bean:
#Named("backing")
#ViewScoped
public class DataScrollerBacking implements Serializable {
private static final long serialVersionUID = 4012320411042043677L;
private static final Logger LOGGER = Logger.getLogger(DataScrollerBacking.class);
private static final Integer CHUNK_SIZE = 10;
#DataSource
#Inject
private String dataSource;
private WebEventDAO webEventDAO;
private List<Event> events;
private Integer totalCount;
private Date startDate;
private Date endDate;
#PostConstruct
public void init() {
webEventDAO = CommonDAOFactory.getInstance(dataSource).getWebEventDAO();
search();
}
public void search() {
DateTime start = new DateTime(2014, 1, 1, 0, 0 ,0);
startDate = start.toDate();
endDate = start.plus(Years.ONE.toPeriod()).minus(Seconds.ONE.toPeriod()).toDate();
try {
totalCount = webEventDAO.getSearchByPeriodRaceTypeAndRaceStatusForCompanyCount(Collections.singletonList(1), startDate, endDate, null, null);
events = new ArrayList<Event>(totalCount);
loadMore();
} catch (DAOException e) {
LOGGER.error("An error occurred while retrieving events.", e);
}
}
public void loadMore() {
List<Event> newEvents = new ArrayList<Event>(CHUNK_SIZE);
try {
newEvents = webEventDAO.searchByPeriodRaceTypeAndRaceStatusForCompany(Collections.singletonList(1), startDate, endDate, null, null, true, events.size(), CHUNK_SIZE);
events.addAll(newEvents);
} catch (DAOException e) {
LOGGER.error("An error occurred while retrieving events.", e);
}
}
public void initViewEventDetails(Integer index, Event event){
LOGGER.info("index=" + index + " eventname=" + event.getName());
}
public String getDataSource() {
return dataSource;
}
public void setDataSource(String dataSource) {
this.dataSource = dataSource;
}
public List<Event> getEvents() {
return events;
}
public void setEvents(List<Event> events) {
this.events = events;
}
public Integer getTotalCount() {
return totalCount;
}
public void setTotalCount(Integer totalCount) {
this.totalCount = totalCount;
}}
In the backing bean, the search method counts the total number of events, saves that information and calls loadMore() to load the first 10 events in the events list.
When the more button is clicked, loadMore() is called again and the next 10 events are appended at the end of events list.
Now when I click on newly loaded elements, the commandLink invokes the backing bean with the correct value.

Best solution to pass objects between two ViewScoped ManagedBeans

I'm wondering what the best practices are to pass data (an object) between two ViewScoped beans.
They need to be view scoped because of the problem that's brilliantly explained here (to put it short: In both views I'm using a h:commandLink from within a h:dataTable which requires the data model to still be present when submitting).
My problem now is that clicking the link also navigates to a new view, so using the following code, my object gets passed but the DetailViewController instance gets killed right after that and a new one is created when the view changes (as you would expect).
View:
<h:dataTable value="#{searchController.dataModel}" var="item">
...
<h:column>
<f:facet name="header">Action</f:facet>
<h:commandLink id="open" value="open" action="#{searchController.showDetail(item)}" />
</h:column>
</h:dataTable>
Bean:
#ManagedBean
#ViewScoped
public class SearchController {
#ManagedProperty(value="#{detailViewController}")
private DetailViewController detailViewController;
// getters, setters, etc. ...
public String showDetail(Item i) {
detailViewController.setItem(i);
return "view_detail.xhtml";
}
}
How would you solve this? I thought about putting the object inside Flash: FacesContext.getExternalContext.getFlash()... Is there an easier or more elegant solution?
You can use view parameters. (See How do you pass view parameters when navigating from an action in JSF2?)
Typically, your method return the url with query parameters:
public String showDetail(Item i) {
return "view_detail.xhtml?id="+i.getId();
}
And in your view_detail.xhtml file, you add a f:viewParam tag evaluating to on of your bean field:
<f:metadata>
<f:viewParam name="id" value="#{myBean.id}" />
</f:metadata>
Then from your backing bean, you use that field to get your Item instance in your #postConstruct method.
If you don't use the f:viewparam tag, you can also fetch the request parameters to obtain the id.
private String id;
private Item item;
#PostConstruct
public void init() {
if (id != null) {
item = fetchItem(id);
} else {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map<String, String> requestParameterMap = externalContext.getRequestParameterMap();
if (requestParameters.containsKey("id")) {
id = requestParameters.get("id");
item = fetchItem(id);
} else {
throw new WebServiceException("No item id in request parameters");
}
}
}

Session Scoped Managed Bean constructor being called on each page refresh

I am using a session scoped managed bean for handling login in a Java EE application. After I authenticate the user, the user object is saved in this session bean. However, after I refresh the page, the session bean values are gone.
I was debugging the code and it results that the constructor of the session scoped managed bean is called again on page refresh, therefore initializing the user object with a new user. I guess this is not a normal behavior since it should be preserved on the session shouldn't it?
I am posting some parts of the login managed bean including the parameters and the login method. Basically the enteredEmail and enteredPassword stand for the entered data on the login form. If the authentication succeeds, the loggedIn boolean is turned to true and the logged in user object is stored in the checkedUser variable.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class LoginController implements Serializable {
#EJB
private LoginSessionBean loginSessionBean;
#EJB
private LecturerFacade lecturerFacade;
private Lecturer checkedUser;
private String enteredEmail;
private String enteredPassword;
private boolean loggedIn;
/** Creates a new instance of loginController */
public LoginController() {
loggedIn = false;
checkedUser = new Lecturer();
}
public String login(){
RequestContext context = RequestContext.getCurrentInstance();
FacesMessage msg = null;
this.setCheckedUser(lecturerFacade.findLecturerByEmail(enteredEmail));
if(loginSessionBean.checkPassword(checkedUser, enteredPassword))
{
loggedIn = true;
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome", checkedUser.getFirstName()+ " " + checkedUser.getLastName());
FacesContext.getCurrentInstance().addMessage(null, msg);
context.addCallbackParam("loggedIn", loggedIn);
}
return "Index";
I am also posting the two EJBs that the above managed bean uses. The lecturerFacade retrieves the user object with the entered email, while the loginSessionBean checks the password.
#Stateless
public class LecturerFacade extends AbstractFacade<Lecturer> {
#PersistenceContext(unitName = "EffectinetWebPU")
private EntityManager em;
Logger logger = Logger.getLogger("MyLog");
FileHandler fh;
protected EntityManager getEntityManager() {
return em;
}
public LecturerFacade() {
super(Lecturer.class);
}
public Lecturer findLecturerByEmail(String email) {
try {
return (Lecturer) this.getEntityManager().createQuery("SELECT l FROM Lecturer l WHERE l.email = :email").setParameter("email", email).getSingleResult();
} catch (NoResultException e) {
System.err.println("Caught NOResultException: "+ e.getMessage());
return null;
} catch (NonUniqueResultException e) {
System.err.println("Caught NonUniqueResultException: "+ e.getMessage());
return null;
} catch (IllegalStateException e) {
System.err.println("Caught IllegalStateException: "+ e.getMessage());
return null;
}
}
_
#Stateless
public class LoginSessionBean {
// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method")
#PersistenceContext(unitName = "EffectinetWebPU")
private EntityManager em;
protected EntityManager getEntityManager() {
return em;
}
public void setEntityManager(EntityManager em) {
this.em = em;
}
public boolean checkPassword(Lecturer user, final String enteredPassword) {
if (user.getPassword().equals(enteredPassword)) {
return true;
} else {
return false;
}
}
}
Please if someone has any suggestion of what is going wrong, please tell me
Im using glassfish 3.1 as application server and Primefaces as JSF library. Also, I have checked and the imported the sessionScoped annotation from the right package and not from javax.enterprise...
Your problem is thus here:
<p:menuitem value="Logout" ... onclick="#{loginController.logout()}"/>
The onclick attribute should represent a JavaScript handler function which is to be executed in the webbrowser when the enduser clicks the element. Something like
onclick="alert('You have clicked this element!')"
The onclick attribute also accepts a ValueExpression, so you can even let JSF/EL autogenerate its value accordingly:
onclick="#{bean.onclickFunction}"
with
public String getOnclickFunction() {
return "alert('You have clicked this element!')";
}
All the EL is thus evaluated when the page is rendered. In your particular case, the logout() method is called everytime the EL is evaluated and thus you're invalidating the session everytime the page is rendered!
You need to bind it to an attribute which takes a MethodExpression like <h:commandLink action>, <h:commandButton action> and in this particular case <p:menuitem action>.
<p:menuitem value="Logout" ... action="#{loginController.logout()}"/>
This can be understood by understanding basic HTML and JavaScript concepts and keeping in mind that JSF ultimately produces HTML/CSS/JS. Open the JSF page in webbrowser, rightclick and View Source to realize it.
Well I managed to solve it today. This was the problem, although I cannot explain why:
I was using Primefaces 3.2 as JSF library so this was the main menu of the index page.
<h:form>
<p:menubar >
<p:menuitem id="registerLink" value="Register" rendered="#{!loginController.loggedIn}" onclick="registerDialog.show()" />
<p:menuitem id="loginLink" value="Login" rendered="#{!loginController.loggedIn}" onclick="loginDialog.show()" />
<p:submenu label="Units" rendered="true">
<p:menuitem id="addNew" value="Add New" onclick="createUnitDialog.show()" />
<p:menuitem id="myUnits" value="My Units" onclick="" />
</p:submenu>
<p:menuitem id="results" value="Results/Statistics" rendered="#{loginController.loggedIn}" onclick=""/>
<p:menuitem id="profile" value="My Profile" rendered="#{loginController.loggedIn}" onclick=""/>
<p:menuitem id="logout" value="Logout" rendered="#{loginController.loggedIn}" onclick="#{loginController.logout()}"/>
</p:menubar>
</h:form>
After setting breakpoints to the whole code I discovered that the logout() method, which is supposed to destroy the managed bean, was called on every page refresh. I don't know why this happened as it should be called when the logout menuitem was clicked.
However, after changing the onclick="#{loginController.logout()} with action="#{loginController.logout()} the problem was solved.
I checked the documentation of Primefaces but nowhere this behavior was explained

Resources