I\'m building my first Java EE application using JSF, PrimeFaces, Glassfish and Netbeans. Because I\'m new, it\'s possible I\'m approaching the core problem wrong.
Core problem: I want to maintain user\'s information securely. There seems to be conflicting ideas on whether it should be maintained in a JSF session bean or a stateful session EJB. I\'m trying to use a stateful session EJB because it is more secure that way.
The problem is that my application seems to be creating multiple instances of that bean when I expect it to create one and re-use it. If I refresh the page it runs the @PostConstruct
and @PostActivate
3 times, all of them with a different instances. Then they all get destroyed when I re-deploy the application.
Did I misunderstand how it should work or is something wrongly configured?
I\'ll try to show a trimmed down code sample:
basic.xhtml
:
<?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://java.sun.com/jsf/html\"
xmlns:c=\"http://java.sun.com/jsp/jstl/core\">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Hello from Facelets
<c:if test=\"#{loginController.authenticated}\">
Authenticated
</c:if>
<c:if test=\"#{loginController.authenticated}\">
Authenticated
</c:if>
<c:if test=\"#{loginController.authenticated}\">
Authenticated
</c:if>
</h:body>
</html>
LoginController
:
@Named(value = \"loginController\")
@RequestScoped
public class LoginController implements Serializable {
@EJB
private UserBeanLocal userBean;
public boolean isAuthenticated() {
return userBean.isAuthenticated();
}
}
UserBean
(excluding UserBeanLocal
interface)
@Stateful
public class UserBean implements UserBeanLocal, Serializable {
boolean authenticated = false;
@PostConstruct
@PostActivate
public void setup(){
System.out.println(\"##### Create user Bean: \"+this.toString());
}
@Override
public boolean isAuthenticated() {
System.out.println(\"########## Authentication test is automatically passing.\");
authenticated = true;//hard coded for simplicity.
return authenticated;
}
@PrePassivate
@PreDestroy
public void cleanup(){
System.out.println(\"##### Destroy user Bean\");
}
}
Finally, here is the Glassfish output after refreshing three times:
INFO: ##### Create user Bean: boundary._UserBean_Serializable@2e644784
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ##### Create user Bean: boundary._UserBean_Serializable@691ae9e7
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ##### Create user Bean: boundary._UserBean_Serializable@391115ac
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.
INFO: ########## Authentication test is automatically passing.