Do scope annotations override managed bean scope definitions in faces-config? [duplicate] - jsf-2

In my application in some places we are using #ManagedBean annoation for Person bean and for the same Person bean we defining in the faces-confing.xml like below at the same time.
#ManagedBean("name=person")
#SessionScoped
Public class Person{
}
faces-config.xml
<managed-bean>
<managed-bean-name>person</managed-bean-name>
<managed-bean-class>com.test.sample.Person</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
my question is does this approach create two instances for the Person bean or it does matter if I do this? Does this have any effect on performance of my application If I do this for every Bean in my application?

There's a priority defined for this case. #ManagedBean annotation avoids having to configure an entry in faces-config.xml but, if you have both, the <managed-bean> entry overrides the annotation.
In your case, there'll be only one instance configured like your faces-config.xml entry. In your case, both approaches are configured the same way but, should you change your faces-config.xml entry to something like
<managed-bean>
<managed-bean-name>personBean</managed-bean-name>
<managed-bean-class>com.test.sample.Person</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
Your bean will be registered under personBean rather than person (which is the name defined by the annotation).

Related

ManagedBean Params not accepted and Bean seemingly not in scope

This uses the same code that comes from
primefaces tree control
#ManagedBean( name = "theName", eager = true)
The first question is why "name" and "eager" are not recognised. Eclipse suggests I change either parameter to "value" - so not sure whats going on there.
Then, where I have been careful to capitalise where necessary and create my bean
public class TreeBean implements Serializable {
and reference it in my xhtml
<h:form id="mainForm">
<p:tree id="treeSingle" value="#{treeBean.root}" var="node"
selectionMode="single"
selection="#{treeBean.selectedNode}">
(paying attention to the capitalisation of the classname).
The output shows only a narrow bar. System.out.println("Constructor called") suggests the bean is not known. To support this, if I press the button as coded in the example (link provided at the top) I get the error
Jan 13, 2014 12:19:26 AM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
SEVERE: javax.el.PropertyNotFoundException: /HelloWorld.xhtml #23,50 selection="#{treeBean.selectedNode}": Target Unreachable, identifier 'treeBean' resolved to null
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:133)
I've run out of ideas now as to what could be the problem. Is there any way of further debugging this or anyone got any ideas about the eager/name thing and what is causing the Bean class to be (I assume) not to be seen.
Thanks in advance.
Kevin
beans should be defined this way:
#ManagedBean(name="treeBean")
#SessionScoped // or whatever scope you would like to use
public class TreeBean implements Serializable {
....
Usage in XHTML: ...="#{treeBean.root}"
Or
#ManagedBean(name="xyz")
#SessionScoped // or whatever scope you would like to use
public class TreeBean implements Serializable {
....
Usage in XHTML: ...="#{xyz.root}"
bean name is just a key for the map, you can name it whatever you want
the scope of the bean should be from the package javax.faces.bean
i.e. for sessionscoped beans you have to import
import javax.faces.bean.SessionScoped;
and for the managedBean Annotation
import javax.faces.bean.ManagedBean;
Here you can find different ways to define a JSF managed bean and also here you can find a really good discuss about managed beans.

jsf 2 application scope bean initiliazed fron faces-config.xml

I'd like to initiliaze the properties of a bean (application scope) from the faces-config.xml. I tried different configuration without success. At library level I'm using jsf 2.2 - jboss-jsf-api_2.2_spec.jar. At project level faces-config is configured to 2.0 version. I don't know if that is the problem. JBDS 7 don't let me to change to 2.2 beacouse of conflict with others Project Facets.
This is the faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<managed-bean>
<managed-bean-name>appBean</managed-bean-name>
<managed-bean-class>package.ApplicationBean</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
<managed-property>
<property-name>cookieNameLocale</property-name>
<property-class>java.lang.String</property-class>
<value>someText</value>
</managed-property>
<managed-property>
<property-name>debug</property-name>
<property-class>boolean</property-class>
<value>true</value>
</managed-property>
</managed-bean>
<application>
<locale-config>
<default-locale>xx_XX</default-locale>
<supported-locale>xx_XX</supported-locale>
</locale-config>
<resource-bundle>
<base-name>locale</base-name>
<var>i18n</var>
</resource-bundle>
</application>
</faces-config>
This is the application scope bean:
public class ApplicationBean implements Serializable {
private boolean debug;
private String cookieNameLocale;
//respectively getters and setters
}
When #Inject the appBean into another session scope bean the properties are not initiliazed. There are not errors and appBean is created before session bean (using #PostConstruct to print)
The <managed-bean> entry in faces-config.xml basically declares a new #ManagedBean. I.e. a JSF managed bean. However, with #Inject you're basically injecting a CDI managed bean.
Those are two mutually exclusive ways of managing beans. Effectively, you end up with 2 instances of the very same bean class, one managed by JSF via faces-config.xml and another one managed by CDI via annotations. Only the one managed by JSF has those properties set.
You've 2 options:
Use #ManagedProperty to inject it as a JSF managed bean. This in turn however requires that the acceptor is by itself also a JSF managed bean.
Forget the faces-config.xml approach altogether. Define them as JNDI resources in either web.xml or server config and use #Resource to inject them. Alternatively, define them as .properties file settings or <context-param> entries in web.xml. CDI doesn't offer ways out the box to inject them, but it's possible to create a custom annotation with a CDI Producer for that.

Are there going to be two instances for a bean if I write #managed bean annotation and define same in faces-config.xml

In my application in some places we are using #ManagedBean annoation for Person bean and for the same Person bean we defining in the faces-confing.xml like below at the same time.
#ManagedBean("name=person")
#SessionScoped
Public class Person{
}
faces-config.xml
<managed-bean>
<managed-bean-name>person</managed-bean-name>
<managed-bean-class>com.test.sample.Person</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
my question is does this approach create two instances for the Person bean or it does matter if I do this? Does this have any effect on performance of my application If I do this for every Bean in my application?
There's a priority defined for this case. #ManagedBean annotation avoids having to configure an entry in faces-config.xml but, if you have both, the <managed-bean> entry overrides the annotation.
In your case, there'll be only one instance configured like your faces-config.xml entry. In your case, both approaches are configured the same way but, should you change your faces-config.xml entry to something like
<managed-bean>
<managed-bean-name>personBean</managed-bean-name>
<managed-bean-class>com.test.sample.Person</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
Your bean will be registered under personBean rather than person (which is the name defined by the annotation).

jsf 2 Session bean created for every request [duplicate]

This question already has an answer here:
#SessionScoped bean looses scope and gets recreated all the time, fields become null
(1 answer)
Closed 6 years ago.
ello
I have 2 Managed beans, one View scoped, the other Session scoped. The View scoped bean is defined as
#ManagedBean
#ViewScoped
public class InvoiceController implements Serializable {
private static final long serialVersionUID = 1L;
#ManagedProperty(value="#{invoiceService}")
private InvoiceService invoiceService;
The session scoped bean as
#ManagedBean
#SessionScoped
public class InvoiceService implements Serializable{
I am using the session scoped bean to hold a flag used to decide if a panel should be rendered, when I run this through the debug I find that every time I call the method on the sesison bean, it is a new instance of the bean and therefore does not retain the value of my flag between requests.
What am I doing wrong?
That can happen if you have imported #SessionScoped from the javax.enterprise.context package instead of from the javax.faces.bean package. The former works on CDI #Named beans only, while the latter works on JSF #ManagedBean beans only.
A JSF #ManagedBean without any valid scope would default to #NoneScoped which means that it's newly constructed on every single EL expression referencing the bean, such as the #ManagedProperty. This explains the symptoms you're seeing.
I had a similar problem. I use a save-method in the view scoped bean that calls a method in the session scoped bean to update some values.
This is what I found out by debugging (excuse my non-Java-guru English):
When first loading the page, the instance number of the injected session bean was for example 111111.
But in the save-method (and all other methods called by an action like a commandButton or action listeners btw), suddenly the session bean was of another instance (say 222222).
Both instances 111111 and 222222 contained the very same values.
All methods I called now were done in the 222222 instance and it changed values in there as I wanted it. But the 111111 instance remained untouched and unchanged.
So 222222 was basically a deep(?) clone of 111111, and not even a copy.
But, after the save-method was done and the page got reloaded, the original 111111 instance was used again in the view scope bean.
The 222222 instance just got thrown to the garbage.
My solution for this problem:
I'm not using the ManagedProperty injection anymore.
Instead I made some helper code to get the session bean wherever I need it (aka in the view scoped bean methods):
public Object getSessionBean(String sessionBeanName)
{
return FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(FacesContext.getCurrentInstance().getELContext(), null, sessionBeanName);
}
For your example above, the call would be:
InvoiceService invoiceService = (InvoiceService) helper.getSessionBean("invoiceService");
Call it in your methods, do not store it as a field in the view scoped bean.
I hope this somehow helps you fix your problem.

what to use, managed beans (backing beans) or entity beans?

I see a lot of examples marking beans as entity beans (#Entity) & named beans (CDI), so as to avoid creating 2 classes (managed bean & entity bean) and also to make use of Bean Validation so that validation can be performed on both client & server.
So should I be using a single class or not, are there any issues or should I be having my managed beans or service layer create entity beans using the data from managed beans ?
The #Named or #ManagedBean annotations are typically used to let the bean container (CDI/JSF) create an instance of a bean on demand when referenced by expression language in JSF.
For an #Entity bean, it often doesn't make that much sense to just get an arbitrary new instance. An #Entity is very strongly connected to a persistent identity. Such an entity is therefor requested from the Entity Manager and not from a bean container.
The typical pattern is to have a (slim) backing bean that's named making a call to a service (which is in turn typically #Stateless in Java EE). The service then returns entities.
In some very trivial systems people sometimes do make the service named and thus directly available to EL. However, eventually you often want to let the "backing code" generate faces messages or handle (table) selections, which are all things that should not be the concern of a pure business service.
Another common shortcut is letting the backing bean contain business code directly (e.g. the entity manager that retrieves the entities). This makes the business code hard to re-use, but if the app is trivial and there's no need for re-use you might get away with it.
But letting the entity -be- the backing bean is rare and anti to the common Java EE patterns.
Just note that the backing bean can return the entity directly, so bean-validation can still be used. There is no need whatsoever for the strange 'scatter/gather' pattern that crept up a long time ago (See the second example in this question).
E.g.
#ViewScoped
#ManagedBean
public class BackingBean {
private SomeEntity myEntity; // + getter
#EJB
private Service service;
#PostConstruct
public void init() {
myEntity = service.getSomeEntity();
}
public void save() {
service.save(myEntity);
FacesContext.getCurrentInstance().addMessage(..., ...);
}
}
Assuming SomeEntity in an #Entity annotated bean, bean validation can now be used on a Facelet like:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
>
<h:body>
<h:form>
<h:inputText value="#{backingBean.myEntity.name}" />
<h:commandButton value="Save" action="#{backingBean.save}" />
</h:form>
</h:body>
</html>
If there's a constraint on SomeEntity.name it will be validated.

Resources