4

I've seen the other questions regarding calling a bean constructor and ViewScope, and I'm still having difficulty. The problem I'm seeing involves two specific pages in my application. The first is a dataTable (for now it is filled with randomly generated data but will eventually call a database), the second page is a fairly simple display page in which information from the selected row is displayed in a form for either editing or viewing - this is my detail.xhtml page. It is the bean for this page that is the issue; its constructor is called twice: first when I navigate to the page, again when I press the commandButton whether to submit changes or cancel changes does not matter, the detail.xhtml backing bean's constructor is called a second time.

My bean is @ViewScoped, importing javax.faces.bean.ViewScoped. A few other details that might make a difference, but if they do I don't understand why: my UserDetailBean.java inherits from a base bean (which I so originally call UIBaseBean.java). Now, my UIBaseBean is @RequestScoped. As I understand, this shouldn't make a difference because my UserDetailBean is @ViewScoped, please correct me if I'm wrong.

The other detail that might make a difference is the setting of a variable in the constructor of both the UIBaseBean and the UserDetailBean. I want to display the location of the user in a toolbar at the top of my pages. To that end I created a variable in UIBaseBean:

protected String toolbarDescription;

I also provided the setter and getter in UIBaseBean. In UIBaseBean's constructor I define the variable:

toolbarDescription = "fix me";

That definition is just so I know to override the variable in the backing bean for any particular page in my application. In my UserDetailBean I assign a new value to the String toolbarDescription. This value is displayed on the detail.xhtml page. Otherwise, the bean for my detail.xhtml page is very straightfoward, it gets and sets properties for the display of data in the form on the detail.xhtml page.

The detail page is set up so the navigation to it happens with a redirect, and the navigation away (when the commandButton is pressed) happens with a redirect. I have tried using faces-config navigation rules with and without redirects, and implicit navigation with and without redirects, but the UserDetailBean constructor is always called twice.

Oh, I set a breakpoint on the toolbarDescription variable in my UserDetailBean constructor, which stops the program twice: when the page is first called, and again after I press the commandButton on the detail page.

From what I've described, can anyone tell me why my constructor is being called twice? Did I design my bean incorrectly, or is the problem deeper in my application?

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import [package name].UIBaseBean;    
import java.util.Locale;
import javax.faces.bean.ManagedProperty;


@ManagedBean
@ViewScoped

public class UserDetailBean extends UIBaseBean {

@ManagedProperty(value = "#{param.action}")
private String action;

private String firstName;
private String lastName;
private String jobTitle;
private String DOH;
private String location;
private String status;
private String comments;
@ManagedProperty(value = "#{param.id}")
private String id;
private String tabTitle;

private boolean editMode;
private boolean viewMode;

private ClUserDetail dBUserDetail;      

    /** Creates a new instance of UserDetailBean */
    public UserDetailBean() {   
        toolbarDescription = CoreMsgBundle.getMessageFromResourceBundle("UserDetail", Locale.ENGLISH);
    }
Sean
  • 971
  • 4
  • 12
  • 21

1 Answers1

4

You need to remove the @RequestScoped and other related annotations from the UIBaseBean (and make it abstract).

Once that is done, you also need to fix the @ManagedProperty on #{param} to be either defined by <f:viewParam> or to be obtained by ExternalContext#getRequestParameterMap() instead. It's namely not possible to inject something which has a shorter scope into something which has a larger scope (because it's not clear which one should be injected since there can be more of them during the scope of the acceptor). JSF would throw an exception on that during bean's construction.

Kounavi
  • 1,090
  • 1
  • 12
  • 24
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you very much, this works exactly as I was hoping the original code would work. As for the @ManagedProperty - that is an example of a little information without good understanding being a bad thing. I read [this answer](http://stackoverflow.com/questions/4888942/viewparam-vs-managedpropertyvalue-param-id) and thought, "oh, what a good idea, I'll do that in my application". – Sean Feb 04 '11 at 18:34
  • @balusc I have a similar issue in that my ViewScoped bean constructor is called multiple times. The bean does extend a base class which provides a utility function but is not a bean itself. The base class has been marked abstract per your answer here, but the constructor is still called twice. Is there any other reasons this could be happening? It may be worth noting that I have declared my beans in faces-config.xml instead of annotations as I am in the process of migrating from 1.2 to 2.0. – Lucas Sep 16 '11 at 18:04
  • 2
    @Lucas: using component bindings like `` or validator/converter attributes like `` or JSTL tags like `` will reconstruct the bean on every request. This is a chicken-egg issue: http://java.net/jira/browse/JAVASERVERFACES-1492 You can go around by turning off partial state saving in web.xml. See also related question which I by coincidence answered today: http://stackoverflow.com/questions/7445417/why-does-fvalidatedoublerange-only-work-for-sessionscoped – BalusC Sep 16 '11 at 18:16
  • @balusc You say bindings _like_ `binding`... Other than `binding` what could they be? Also, my site consists of a single page that has various chunks of the page `ui:include`d, would a `binding` in one that is not included in the current rendering still cause this? – Lucas Sep 16 '11 at 18:27
  • @Lucas: F5. I realized that and already improved the comment. As to ``, there was similar bug in early Mojarra versions. Ensure that you're using most recent version (2.0.6 or 2.1.3). – BalusC Sep 16 '11 at 18:28
  • @balusc I updated from 2.1.2 to 2.1.3, but no dice. I am working on stripping this down to a minimal version that I may be able to share. – Lucas Sep 16 '11 at 19:07
  • @balusc As this comment chain is getting long, I have posted a formal question here: http://stackoverflow.com/questions/7449873/viewscoped-bean-getting-constructed-on-every-request-part-99 – Lucas Sep 16 '11 at 20:10
  • @Lucas: I posted an answer. Coming back to the similar `` bug I was initially talking about, that was a different one. The `src` wasn't properly evaluated upon postback which caused that all form inputs in the include file were not processed. Sorry about that, so your concrete problem with `` is actually caused by the same chicken-egg issue 1492. – BalusC Sep 16 '11 at 20:48