Home » Java » Enterprise Java » ADF: Backing bean scope in task flow finalizer

About Eugene Fedorenko

ADF: Backing bean scope in task flow finalizer

Introduction
This is very common and recommended practice to use task flow finalizers when we need to do some final job (clean resources, close connections, etc) before the task flow is gone. As usual we work with managed beans declared inside the task flow. The managed beans can have different scopes – request, page flow, view, backing bean, etc. The scope depends on what the bean is actually used for. There is a small problem when we access to the backingBean scope managed bean in the finalizer. Let’s have a look at the example bellow.
We have a bounded task flow with page fragments:
And we have manged beans inside the task flow of three different scopes – page flow, view and backingBean:
 <managed-bean id="__3">
  <managed-bean-name id="__5">FlowBean</managed-bean-name>
  <managed-bean-class id="__4">view.BackBean</managed-bean-class>
  <managed-bean-scope id="__2">pageFlow</managed-bean-scope>
 </managed-bean>
 <managed-bean id="__9">
  <managed-bean-name id="__6">ViewBean</managed-bean-name>
  <managed-bean-class id="__7">view.BackBean</managed-bean-class>
  <managed-bean-scope id="__8">view</managed-bean-scope>
 </managed-bean>
 <managed-bean id="__10">
  <managed-bean-name id="__11">BackBean</managed-bean-name>
  <managed-bean-class id="__12">view.BackBean</managed-bean-class>
  <managed-bean-scope id="__13">backingBean</managed-bean-scope>
 </managed-bean>
On the page we have three buttons binded to managed beans of each scope:
  <af:commandButton text="commandButton 1" id="cb1"
     action="go" binding="#{backingBeanScope.BackBean.button}">
  </af:commandButton>

  <af:commandButton text="commandButton 1" id="cb2"  
    binding="#{viewScope.ViewBean.button}"/>

  <af:commandButton text="commandButton 1" id="cb3"  
    binding="#{pageFlowScope.FlowBean.button}"/>

The bean class has the button attribute and testString attribute that signals whether the button is assigned:
  private RichCommandButton button;
  
  public void setButton(RichCommandButton button)
  {
    this.button = button;
  }

  public RichCommandButton getButton()
  {
    return button;
  }

  public String getTestString()
  {
    if (this.button == null)
      return "The button is not assigned";
    else
      return "The button is assigned";
  }


When we press cb1 we go to the return activity and the finalizer gets executed:
public static String resolveExpression(String expression)
 {
   FacesContext fc = FacesContext.getCurrentInstance();
   return (String) fc.getApplication().evaluateExpressionGet(fc, expression,
                                                    String.class);
 }

public void theFinalizer() 
{
  //Just to have test access to the managed beans
  //and to be sure we work with the same instances
  System.out.println(resolveExpression("#{pageFlowScope.FlowBean.testString}")+
                     " " + resolveExpression("#{pageFlowScope.FlowBean.button}"));
  System.out.println(resolveExpression("#{viewScope.ViewBean.testString}")+
                     " " + resolveExpression("#{viewScope.ViewBean.button}"));
  System.out.println(resolveExpression("#{backingBeanScope.BackBean.testString}")+
                     " " + resolveExpression("#{backingBeanScope.BackBean.button}"));
}




Run the application, press the cb1 button and see the following in the system log:
The button is assigned RichCommandButton[UIXFacesBeanImpl, id=cb3]
The button is assigned RichCommandButton[UIXFacesBeanImpl, id=cb2]
The button is assigned RichCommandButton[UIXFacesBeanImpl, id=cb1]
Everything seems to be ok. The task flow is finished and in the finalizer we work with correct managed bean instances. In this test the task flow is finished correctly using Return activity.
And now let’s abandon our task flow – just go away from the page the task flow is put on. The finalizer is executed as well, and have a look at system out:
The button is assigned RichCommandButton[UIXFacesBeanImpl, id=cb3]
The button is assigned RichCommandButton[UIXFacesBeanImpl, id=cb2]
The button is not assigned
This means that we work with different instance of the backingBeanScope.BackBean! In case of abounded task flow the controller don’t see correct backingBeanScope in the finalizer, it is empty and the controller create new instance of the BackBean. At the same time pageFlowScope and viewScope work perfect. So, be careful when you use backingBean scope managed beans within task flows, especially when you access them in finalizers. But in any case you can use the same trick described in the previous post.
That’s it!
Reference: Backing bean scope in ADF task flow finalizer from our JCG partner Eugene Fedorenko at the ADF Practice blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*


eight + = 13

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Do you want to know how to develop your skillset and become a ...

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!
Get ready to Rock!
To download the books, please verify your email address by following the instructions found on the email we just sent you.

THANK YOU!

Close