Separate Managed bean for a popup dialog - jsf

I have three screens(views) associated with separate managed beans for each view.
And, I have a common pop-up dialog which can be opened in all the views.
Can I define a managedbean separately for the pop-up with state #NoneScoped; and maintain an instance of it in each parent bean?? or
Do I need to maintain pop-up data in all three parent views?
Please, suggest me the best practice.

I think this is what you are looking for (check out the answer by BalusC) -
Whats the correct way to create multiple instances of managed beans in JSF 2.0
And since you are using #NoneScoped (unlike #RequestScoped in the above question), I also recommend you to look at this answer by BalusC (about #NoneScoped) -
what is none scope bean and when to use it?
And according to this answer, you can't maintain any instances of a managedbean that is none-scoped, as they are garbaged as soon as they are used.
So, in your case since you have three separate views, for each view, the bean is constructed and used to build the view and garbaged. (Looks like it does not even last for a request cycle). When you request another view, it will be a separate instance.
To have multiple intances of a bean, you can have three properties in a Session-Scoped been (to make them survive across multiple views).
#ManagedBean
#SessionScoped
public class Parent {
private Child child1;
private Child child2;
private Child child3;
// ...
}

Related

How to update bean in database on a RequestScoped view?

First of all, sorry for my english. I have a RequestScoped ManagedBean in order to send parameters to other views, without getting the The scope of the object referenced by expression is shorter than the referring managed beans error. I also have in the same RequestScoped view a p:dataTable showing these beans objects, with an update button for each row, that retrieves this bean to another form in the same view to be update with new values.
The problem is, when I hit the submit button to record the new values, another record is created, instead of the older one being updated. Of course, because the bean is killed when the submit button is pressed (RequestScoped), creating a new bean and another record in the DB. How can I fix it in this scope?
I've seen some alternatives using #PostConstruct here, however I'm not entirely sure it would solve my specific problem.
EDIT:
After researching a bit more into this topic, I came to another doubt: I am using the same Bean in both views (in my case, ProjectBean), should I create a new Bean with RequestScoped annotation (something like ProjectIdBean), set the older one to ViewScoped (so I can reproduce updates naturally on my Database), and let this new Bean handle the requests for other views?
Submit button:
<p:commandButton value="Gravar" action="#{projetoBean.gravar}"
process="#form" update="#form :formTabelaProjetos:tabelaProjetos" />
'Gravar' method:
public void gravar() {
System.out.println("Gravando projeto " + this.projeto.getNome());
ProjetoDAO dao = new ProjetoDAO();
if (this.projeto.getId() == null) {
dao.adiciona(this.projeto);
projetosAtivos = this.getProjetosAtivos();
} else {
dao.atualiza(this.projeto);
}
this.projeto = new Projeto();
}
You can use request scoped backing bean for updating entities. The problem is, that the request life cycle ends when your page is rendered. So anything you loaded will get discarded. The submit creates another request, that will try to reload resources, but it is a different request than the previous one and for example request parameters often do not contain what the programmer expects. But this is what you found out already. There are two ways how to deal with the problem:
1) use simple getters and setters to set "String, Integer" and similar variables in your request scoped bean, that you use to reconstruct and modify the entity you want to update. It is not convenient for the programmer but request scoped beans save resources of your server.
2) change the scope of your backing bean. Session scope is not ideal, because it can stay in memory for a really long time. And you might realize you need to clean it up manually. Much better is ViewScoped bean as it allows you to work with the entities you loaded over several steps. It gets wiped out when the user leaves the page.
#javax.faces.bean.ViewScoped
#javax.faces.bean.ManagedBean
public class SomethingBean {
......
}

jsf multiple instances managed bean for multiple tabs

There is a managed bean(DemoManagedBean.java) which holds some data on the (sample.xhtml)XHTML page.
There is a redirection link in the sample.xhtml which opens a new tab of the same page(sample.xhtml) but with different data loaded.
Issue - since there is only one instance of the DemoManagedBean.java, therefore not able to process anything further i.e; changes on one tab affect all the other tabs.
Is there a way so that I can have a multiple instances for every tab holding the data for the particular tabs?
Thanks,
Dinesh
You control that by setting the right bean scope. In your particular case, you need to put the bean in the request scope or in the view scope, depending on if you need a per-view based state or not.
Using the standard JSF bean management API, that would be just this (no XML needed!):
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean
#RequestScoped
public class DemoManagedBean {
// ...
}
When the #XxxScoped scope annotation is not specified, it defaults to #NoneScope. Your description however matches the session or application scope. Perhaps you've explicitly set the #SessionScoped or #ApplicationScoped annotation while not really understanding what you were actually doing. Or perhaps you're for some reason using Spring to manage beans, a Spring #Controller without any explicit scope specified defaults to application scope.
See also:
How to choose the right bean scope?

Scalability and Thread Safety of Application Scoped ManagedBean Methods

During testing a weakness was exposed in how our app builds f:selectItems lists, specifically, entering really long names on some of our entities screws page alignment by making really wide selects.
Many of these selectItem lists are duplicated in multiple views and backing beans, so I'd like to consolidate their creation.
We already have an application scoped bean that provides List<SelectItem> for enums, and my initial thought was to place them there.
I have some questions, though. We're using jsf 1.2 (if that matters)
1) My understanding is that application scoped beans are singleton simply because a single instance is instantiated and placed in session context. They are not like EJB3 singletons in that only one thread can access any method, so multiple requests won't block trying to access different methods. Is that correct?
2) I suspect each method would have to be synchronized to prevent multiple threads calling the same method from clobbering each other. Is that the case even if the only class member accessed in the method is a threadsafe stateless #EJB?
Following is an implementation of one of them that would be used in 20 views. The implementations for 10 other entities would be similar. Also, the appropriate converters are registered.
public synchronized List<SelectItem> getAccountSelect(){
List<Account> list = new ArrayList<Account>(pemEJB.list(Account.class));
Collections.sort(list, new AccountByActiveByName());
List<SelectItem> result=new ArrayList<SelectItem>(list.size());
for(Account row : list){
result.add(new SelectItem(row,
StringUtil.prefixTruncate(row.getName(), MAX_ACCT_LENGTH, row.isActive())));
}
return result;
}
Any advice appreciated
If it's really mandatory to do the data loading in a getter instead of in the constructor/postconstruct, then there's definitely no point of making it an application scoped bean. Just make it a request scoped one where you do the data loading job in the constructor/postconstruct.
In the jsf applications I work on we load almost all of our reference data (values for selectOneMenues primarily) in Application scope beans and we set up the values in the Constructor of those beans. The data is then available to other managed beans and views via getters but is globalized and centralized for the application. Since the values are only read via getters there is no need for synchronization.
We then expose the beans as mbeans through jmx with a reload method so that they can be updated as needed. The reload method(s) are synchronized so as to block during the short reloads.
In your example above it seems like you could just return a Collection of selectItems so as long as the values are setup in advance you can use this method and still serve multiple threads just fine:
public List<SelectItem> getAccountSelectItems() {
return this.accountSelectItems;
}
Just add this private member to your bean:
private List<SelectItem> accountSelectItems;
and set it up in the constructor:
public AccountBean() {
List<Account> list = new ArrayList<Account>(pemEJB.list(Account.class));
Collections.sort(list, new AccountByActiveByName());
this.accountSelectItems = new ArrayList<SelectItem>(list.size());
for(Account row : list) {
this.accountSelectItems.add(new SelectItem(row, StringUtil.prefixTruncate(row.getName(), MAX_ACCT_LENGTH, row.isActive())));
}
}
If on the other hand this is data that is constantly changing and needs to be updated you might be better off just loading it per session or per request, though you can reload it periodically in application scope using Quartz or some other timer to keep the data reads from your data source down if real time is not an essential requirement for this data in your app. If you are reloading the data then you will want to synchronize those operations if you're using application scope.

Separation of concerns in JSF Beans?

Im currently using JSF2, and i notice the JSF bean could have a lot of responsibility, and if combined will look like lots of codes. These include :
holding the state / data
could be a backing bean for the UI component
action methods definition
action listener methods definition
navigation
calling the services
all the setter n getters
Does it make anysense to break these into several classes or do you usually combine all of them together ?
Currenly for every JSF Bean, i define another class to hold the view data / state along with the setter getters.
How do you usually do it ? Please share your experience !
Thank you =)
Every property which is been used in action(listener) methods needs to stay in the backing bean. The remnant most likely belongs in its own class which can in turn be a different (managed/entity)bean, eventually as a (managed)property of the bean where it originated.

How to layout beans for single page design

Hey guys. I'm designing a site that uses the Icefaces framework. I've been reading a book called Real World Java EE patterns. I'm kind of confused how to layout the pages. Normally I would have just a POJO class implement serializable for a bean. This bean would then back each page. With a single page design I'm going to have a bunch of elements on the page. Datatables, trees, inputs, calendars etc. Is it normal or best practice to have separate beans for each datatable, calendar, etc or put that all in one bean? I'm not sure how to approach this. Right now each element is a bean and I'm using the #Inject annotation to have the data table talk to the tree and vise versa. This creates really bad code and if I put this as a member of the class I will get a circular reference because the data table bean has to inject the calendar and the calendar has to inject the data table.
Thanks for any help.
I tend to use a single bean per <h:form> or at least per view (XHTML/JSP file). Any related beans will just be injected in this particular "main" bean (and thus not among each other).

Resources