is it possible to inherit class into #managedbean - jsf

i am using jsf 2.1.26 , and primefaces 3.5
here is the code..
HescoBusinessBean
public abstract class HescoBusinessBean {
private String mod = "";
// setter and getter
}
BudgetReservedBean
#ManagedBean(name = "budgetReservedBean")
#ViewScoped
public class BudgetReservedBean extends HescoBusinessBean implements Serializable {
// other beans properties with setter and getter
}
BudgetReservedAction
#ManagedBean
#RequestScoped
public class BudgetReservedAction implements Serializable {
#ManagedProperty(value = "#{budgetReservedBean}")
private BudgetReservedBean budgetReservedBean;
// setter and getter
}
abc.xhtml
<h:outputText value="#{budgetReservedAction.budgetReservedBean.mod}" />
<!--where 'mod' property in HescoBusinessBean-->
// getting error on server log
org.apache.el.parser.ParseException: Encountered " "mod" "mod "" at line 1, column 43.
Was expecting:
<IDENTIFIER> ...
can anyone help me out ? thanks in advance

mod is an EL reserved word. See here the list of all reserverd words.
Your implementation of bean inheritance is correct.

Related

Set JSF managed bean property from JAX-RS endpoint

I have a JSF managed bean and a JAX-RS web service.
ManagedBean - myBean class
#ManagedBean
#ViewScoped
public class MyBean implements Serializable {
private String id;//getters && setters ommited
}
Web Service - myService class
#ApplicationPath("/myService")
#Path("/")
#Consumes("application/json")
public class MyService extends Application {
#Inject
MyBean myBean;
#Path("doSth")
#POST
public Response doSomething(){
//make an action here and set myBean.id value
myBean.id = 'a random value';
}
}
I debugged the code above, but then I realised that inside myBean class, the property "id" was equal to null even though I had set it in the doSomething() method before, is it possible to achieve the scenario described above with these technologies? Before #Inject, I also tried the injection of my managedBean using #ManagedProperty, but the managedBean was null and not injected.
Then I would like this myBean.id property to be changed for the bean when I call it using myBean.id, is that feasible?
Thanks in advance!

Safest way to access a session scope bean in another bean

I am new to jsf and using JSF 2.0 to keep user information in a session scoped bean. I need to access this information across other beans for grunt work. Presently, this is how i am doing:-
private UserBean myuser1 = (UserBean)FacesUtils.getManagedBean("UserBean");
and then access properties as
if (myuser1.getUserType == 1) ...
this works but some time throws Argument Error: parameter key is null exception. I have been using following method too:-
private UserBean myuser2 = new UserBean();
if (myuser2.getUserType == 1) ...
In second method, my understanding is that if UserBean is already created in session, it would be retried. There are lots of question about 'how to access one bean in another' so i am confused. Please tell me one clean method which should always work and not throw null pointer exception abruptly.
The simplest way I know of is using #ManagedProperty, I don't know what you mean by safest though.
Let's say this is your sessionScoped bean :
#ManagedBean
#SessionScopped
public class UserBean {
//bean attributes and methods
}
Then you can access it in any other bean (provided it has the same or a narrower scope) as an attribute like this :
#ManagedBean
#ViewScoped //in this cas you can use SessionScoped, FlowScoped, or RequestScoped too
public class AnotherBean {
#ManagedProperty("#{userBean}")
UserBean userB;
//rest of the bean
//be sure to add getters and setters for the injected bean
}
For more details check this
Hope this helps.
Actually,
parameter key is null exception: it's either you didn't initialize the object witch can be solver with either adding
object = new Object(); // in the constructor of the class.
The second problem may be that the object is " DETACHED " you need to call the object using the method merge (with the entity manager).
A detached object is a known value but the JPA system doesn't know if it is the latest version from the DB or even sometimes the id value is not set for some reason (Not managed with jpa in other words it can be your case).
If em is your entity manager and you have the following function:
public Object latestVersion(Object o){ em.merge; }
In your Bean with:
#EJB
Service service;
if you do em.latestVersion(o); the problem of detached object is solved.
And for the real answer:
To access a object from another view you can simply do the following.
#ManagedBean
#SessionScoped
..... Bean1 {
public static Object o;
.....
}
#ManagedBean
..... Bean 2 {
private Object b=Bean1.o;
.....
}
Good luck
The standard practice of setting dependency of a scoped bean in another scoped bean is to use #Inject annotation like
#Inject UserBean userBean; in the bean you want use the UserBean object.
Your UserBean should be a stateful one.
#Stateful
#LocalBean
public class UserBean
{
private String name;
public String getName() { return name; }
public void setName( String name_ ) { name = name_; }
}
And just inject it into a stateless bean to modify its state:
#Stateless
#LocalBean
public class MyStatelessBean
{
#EJB
private UserBean userBean;
public String getUserName() { userBean.getName(); };
public void setUserName( String name_ ) { userBean.setName( name_); }
}
Or you can access it from (not wider scoped) managed beans as well in the same way:
#ManagedBean
#Dependent
public class MyJSFManagedBean
{
#EJB
private UserBean userBean;
}
You wrote in your comment you does not use EJBs at all. The picture modify like this:
The UserBean should be a SessionScoped CDI bean
#Named
#SessionScoped
pubilc class UserBean
{}
The othe CDI bean should be in a nearer scope:
#Named
#Request // or #ViewScoped or #Dependent
public class OwnerBean
{
#Inject
UserBean userBean;
}
The container automatically takes care to create the beans in the right scope and insert them into the owers (any kind of container managed objects : servlets, filters, action listeners, JSF/CDI beans). You need to insert a wider scoped resource into a thinner scoped one.

After migration from JSF #ManagedBean to CDI #Named, constructor called multiple times and submitted input values always null

Edit: The comment section solved my problem! The problem was that I was using incorrect imports for the Scopes.
I have a simple JSF application (login, pull data from database, allow user to edit data). It works well, I want to update the code to use CDI (Weld), but I am having trouble.
I am following / looking at: http://docs.jboss.org/weld/reference/latest/en-US/html/example.html
Original stuff without Weld:
login.xhtml
<h:form id="inputForm">
<h:panelGrid columns="2" cellpadding="5" cellspacing="1">
<h:outputText id="nameDesc" value="Name"></h:outputText>
<h:inputText id="nameInput" value="#{login.loginName}" binding="#{name}"></h:inputText>
<h:outputText id="passwordDesc" value="Password"></h:outputText>
<h:inputSecret id="passwordInput" value="#{login.password}" binding="#{password}"></h:inputSecret>
</h:panelGrid>
<h:commandButton value="Login" action="#{login.login(name.value, password.value)}"/>
</h:form>
LoginBean.java:
#ManagedBean(name="login")
#SessionScoped
public class LoginBean implements Serializable {
private static final long serialVersionUID = 1L;
#ManagedProperty(value="#{db}")
private DatabaseBean db;
private String password;
private String loginName;
// other stuff and functions
public String getLoginName () {
return loginName;
}
public void setLoginName (String name) {
this.loginName = name;
}
public String getPassword () {
return password;
}
public void setPassword (final String password) {
this.password = password;
}
public void setDb(DatabaseBean db) {
this.db = db;
}
DatabaseBean.java:
#ManagedBean(name="db", eager=true)
#ApplicationScoped
public class DatabaseBean implements Serializable {
#PostConstruct
public void init() {
//... connect to database etc
}
}
---------What I tried to get it running with Weld (only changes from above to make it a bit shorter): --------
LoginBean.java, changed to #Named from #ManagedBean, added #Inject for DatabaseBean
#Named("login")
#SessionScoped
public class LoginBean implements Serializable {
// stuff
private #Inject DatabaseBean db;
}
DatabaseBean.java, changed to #Named from #ManagedBean:
#Named("db")
#ApplicationScoped
public class DatabaseBean implements Serializable {
}
LoginBean has a function:
public String login(String name, String password) {
System.out.println("login called"+name);
// other stuff
}
With my second implementation (the one where I try to use Weld), the print is called once: "login called", and the username is empty (I checked this with name.IsEmpty()).
I have also tried injecting it by constructor:
loginBean.java
#Inject
public LoginBean(DatabaseBean db) {
System.out.println("constructor");
this.db = db;
}
When I do this the I get lots of "constructor" prints, so it is called several times, but I don't see why - I guess this is the problem though, only one instance of LoginBean gets the input (username and password) and then lots of new ones are created for some reason. Why is that?
I use Eclipse and Tomcat8 to run it.
Thank you for reading!
managed bean constructor called multiple times
CDI may call constructor more often than expected while generating/creating enhanced subclasses/proxies. See also Field.get(obj) returns all nulls on injected CDI managed beans, while manually invoking getters return correct values. Just do not log constructor invocation, it would only confuse yourself. #PostConstruct is the only interesting method to hook on.
the print is called once: "login called", and the username is empty (I checked this with name.IsEmpty()).
As to the concrete problem of form input values being null when the action method is invoked, and thus the #SessionScoped CDI managed bean seemingly being recreated on every access, this matches the behavior of a #Dependent scoped bean. This is the default scope when no valid CDI managed bean scope can be found. See also What is the default Managed Bean Scope in a JSF 2 application?
This in turn suggests you imported #SessionScoped from the wrong package. Make sure it's from the javax.enterprise.context package and not from e.g. javax.faces.bean. JSF managed bean scopes are not recognizable as valid CDI managed bean scopes.
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
#Named("login")
#SessionScoped
public class LoginBean implements Serializable {
// ...
}

Pass a param from ManagedBean to jsf page

I am working with JSF 2.2 and Tomcat 8 and I am just starting to play with them.
I have a command button in a jsf page.
<h:commandButton id="newObject" value="New Object" action="#{someObject.someAction}">
<f:param name="object_id" value="#{someObject.object_id}" />
</h:commandButton>
The ManagedBean is similar to this:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
#ManagedBean
public class SomeObject implements Serializable{
private static final long serialVersionUID = 1L;
private int object_id;
public int getObject_id() {
return object_id;
}
public void setObject_id(int object_id) {
this.object_id = object_id;
}
public String someAction() {
setObject_id(sqlInsert());
if(getObject_id() != 0) {
System.out.println(getObject_id());
return "new_page";
}
}
}
The sqlInsert method is working fine. I use it to insert a new row in some sql table and get the auto generated key, which is an int. If the insert did not happen it would return 0.
I can navigate to the new_page, but the param object_id is 0. I added println to show the object_id and it is the actual key.
What am I doing wrong?
Since you are using the only #ManagedBean annotation on your Managed Bean and not specifying any Scope of you bean explicitly, your Bean will act as if its a #RequestScoped bean.[See link]
So every time you click your New Object button, the Bean is re initialized and you will loose the state(variable values).
Think and decide which scope you want to use [See link]. For your requirements #ViewScoped might do the job for you.

How to inject different subclasses as ManagedProperty JSF 2?

I'm new to JSF and I'm wondering if it's possible to inject different subclasses of a base class as a MangedProperty, depending on different situations? For instance, I have this managed bean:
#ManagedBean
#SessionScoped
public class Claim implements Serializable {
private Loss lossDetails; //need to inject one of two subclasses
}
And the following base class:
public class Loss implements Serializable {
private String lossCause;
private String lossDescription;
}
Which has two subclasses:
public class AutoLoss extends Loss implements Serializable {
private List<String> vehicles;
//...
}
public class PropLoss extends Loss implements Serializable {
private String property;
private boolean weatherRelated;
//...
}
Depending on selections that are made on my application's JSF pages, I want to inject one of the subclasses as the lossDetails ManagedProperty in the Claim managed bean. Since I can't give the two subclasses the same managed bean name and I don't know ahead of time which one needs to be injected, is this something that can be accomplished in JSF? Or is there a different approach I should be considering?
Thanks!
You can't and shouldn't.
It's not possible to inject a request scoped value as managed property in a session scoped bean.
Entities should not be treated as managed beans.
Rather pass it as method argument instead:
<h:dataTable value="#{lossManager.losses}" var="loss">
<h:column>
<h:commandButton value="Claim" action="#{claim.doAction(loss)}" />
</h:column>
</h:dataTable>
With in Claim managed bean:
public void doAction(Loss loss) {
// ...
}

Resources