I am currently building an application of which the (customer) requirements are Java EE and JSF (Primefaces) as front-end.
In this application I need to create a kind of wizard with several steps. I thus created a backing bean which holds the information of the several steps and a controller which handles the clicks and actions in the form, hence depending strongly on the Bean.
Problem is that the Bean although annotated as Sessionscoped is recreated every single time the controller is invoked. Hence, I get nullpointers and such since fields which I expect to be initiated remain null.
This is a part of the code of the bean:
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import java.io.Serializable;
#SessionScoped
#Named
/**
* A placeholder for all the information needed in the wizard.
*/
public class WizardBean implements Serializable {
And this is part of the code for the controller:
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
#ManagedBean(name = "registerInvestigationController")
#SessionScoped
public class WizardController implements Serializable {
private static final long serialVersionUID = 3327044905245768948L;
private static final Logger LOGGER = LoggerFactory.getLogger(WizardController.class);
#Inject
private WizardBean wizardBean;
Any idea what I am doing wrong?
Related
I am trying to run my Web application in netbeans with wildfly server. I got error
"jboss.naming.context.java.module.LocalShop.LocalShop.env.ReadBean.dp is missing [jboss.naming.context.java.jboss.datasources.shopstyles]" and I think line
#Resource (lookup= "java:jboss/datasources/shopstyles") is causing the error. Can someone help me?
Package structure
MANIFEST.MF
My code for web application in netbeans:
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import javax.sql.DataSource;
#Named (value="readBean")
#RequestScoped
public class ReadBean implements Serializable {
#Resource (lookup= "java:jboss/datasources/shopstyles")
private DataSource dp;
public List<Veggie>performRead() throws SQLException{
if(dp == null){
throw new SQLException("Cannot access data pool");
}
List<Veggie>list;
try (Connection con =dp.getConnection()){
if(con == null){
throw new SQLException("Cannot establish connection to database");
}
PreparedStatement ps =con.prepareStatement("select veggie_id,name,price,created_date from veggie");
ResultSet result =ps.executeQuery();
list=new ArrayList<>();
while(result.next()){
Veggie veggie=new Veggie();
veggie.setVeggieID(result.getInt("veggie_id"));
veggie.setName(result.getString("name"));
veggie.setPrice(result.getString("price"));
veggie.setCreated_date(result.getDate("created_date"));
list.add(veggie);
}
}
return list;
}
}
Manifest.mf code:
Manifest-Version: 1.0
Netbeans config
Part of Standalone
I'm beggining with Hibernate Envers. I'm already able to properly annotate classes with #Audited and create revisions, but I'm unable to record logged user data with my revisions.
My JSF 2.0 test application is running on CDI, JPA/Hibernate in a jbossEAP6 / wildfly server. I'm neither using Spring or Seam.
Here is some code:
revisionEntity.java
#Entity
#RevisionEntity(AuditListener.class)
public class RevisionEntity {
#Id
#GeneratedValue
#RevisionNumber
private int id;
#RevisionTimestamp
private long timestamp;
private String username;
LoginBean.java
#Named
#Stateful
#SessionScoped
public class LoginBean implements Serializable{
private String username;
...
AuditListener.java
import javax.ejb.Stateful;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.hibernate.envers.RevisionListener;
import br.test.login.filterlogin.beans.LoginBean;
#Named
#Stateful
#SessionScoped
public class AuditListener implements RevisionListener {
#Inject
private LoginBean loginBean;
public void newRevision(Object revisionEntity) {
RevisionEntityEx RevEntity = (RevisionEntityEx) revisionEntity;
RevEntity.setUsername(loginBean.getUsername());
}
The loginBean injection fails, giving me a NullPointerException. Any ideas?
Sorry about my terrible grammar.
Regards,
Marcelo.
The listener is not managed by the container so your loginBean will not be injected.
We need to lookup for it...
Notice that UsuarioService should be changed to your type: LoginBean.
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.CDI;
BeanManager beanManager = CDI.current().getBeanManager();
Bean<UsuarioService> bean = (Bean<UsuarioService>) beanManager.getBeans(UsuarioService.class).iterator().next();
CreationalContext<UsuarioService> context = beanManager.createCreationalContext(bean);
this.usuarioService = (UsuarioService) beanManager.getReference(bean, UsuarioService.class, context);
You didn't give any stacktrace, so I'm guessing. AFAIK you cannot combine together both
#Stateful
#SessionScoped
Because the first annotation is for making a class an EJB stateful session bean, but the second one is for making class a CDI managed bean, with scope Session.
It seems to me that you are trying to use technologies you don't understand at all. Please read a specification or at least some CDI tutorials/ sample GitHub projects.
Personal advice: most of the time you should prefer to use #Stateless over #Stateful for EJB beans. Then all data related to HTTP session you can store e.g. in some additional #SessionScoped CDI bean.
can someone help out, I just don't get it, the other bean works fine, i'ts just that bean that sucks:
BEAN:
import java.io.Serializable;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#SessionScoped
#Named
class FeedbackController implements Serializable {
private static final long serialVersionUID = 1L;
private Lecture lecture;
private List<Feedback> filteredFeedbacks;
public Lecture getLecture() {
return lecture;
}
public void setLecture(Lecture lecture) {
this.lecture = lecture;
}
VIEW:
<p:dataTable var="feedback"
value="#{feedbackController.lecture.feedbacks}"
ERROR:
javax.el.PropertyNotFoundException: The class 'com.xxx.controller.FeedbackController' does not have a readable property 'lecture'.
Since I'm quite nooby to the subject, i dont even know what i'm possibly doing wrong. I dont get, why it is not possible to access 'lecture' when the Controller is #Named and has a public getLecture() method. Also to say, is that i've got another view with the same priciple and it works fine, so i suppose to know what i'm doing.
Thanks in advance!
fixed it:
Must be public class FeedbackController implements Serializable {
thanks to BalusC for helping me out!
#ManagedProperty("#{sessionBean}") is not injected properly. The sessionBean is declared in a JAR file and it has a JSF 2.0 compatible faces-config as well.
But when I use
FacesContext context = FacesContext.getCurrentInstance();
sessionBean = (SessionBean) context.getApplication().evaluateExpressionGet(context, "#{sessionBean}", SessionBean.class);
It evaluates the session bean correctly. What is the reason?
EDIT: The bean that I want to be injected(sessionBean) is in a JAR file which is annotated as #ManagedBean and #SessionScoped. Also the JAR contains a JSF2 compatible faces-config in the META-INF/resources
1.) Where are you injecting the sessionBean into? Show us the class definition. Is the class a #ManagedBean?
2.) Check if the setter setSessionBean(SessionBean sb) called.
3.) Is the provided value in the setter null?
4.) You can also try to do the following:
#PostConstruct
private void init() {
FacesContext context = FacesContext.getCurrentInstance();
sessionBean = (SessionBean) context.getApplication().evaluateExpressionGet(context, "#{sessionBean}", SessionBean.class);
}
... and check if the sessionBean is evaluated correctly.
For me this was an issue with packages, the following imports worked for me:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
Before I was using a combination of different packages (auto-imported by IDE):
import javax.faces.bean.ManagedProperty;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
I use CDI to annotate beans. One bean called SessionManager holds the logined user information with the declaration:
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.ejb.Stateful;
#Stateful
#Named
#SessionScoped
public class SessionManagerImpl implements SessionManager, Serializable {
...
public UserDto getLoginedUser() {
...
}
}
And the other is called DashboardController as:
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import javax.inject.Inject;
#Named
#RequestScoped
public class DashboardController implements Serializable {
#Inject
private SessionManager sessionManager;
...
public void loadUserInfo() {
...
UserDto userDto = sessionManager.getLoginedUser();
}
}
The first time i open a page refer DashboardController, it works well. And if i continue to use the website, it still works. But if i don't click any page for some minutes, and come back to open the page, it will display a null pointer for the javassist$$getLoginedUser method invocation (sessionManager is not null when i use debug to watch). The session is still valid for i can get values from session map directly using faces context.
What's wrong with the SessionManager? Thanks.
This occurs because your Stateful Session Bean (EJB) has passivated, and is not reintroduced to your session. If there isn't a strong need to make your session scoped object a session bean, I would just make it a SessionScoped managed bean.