0

Please note: This question is about CDI scopes as we are using CDI scopes in the app and not JSF scopes.

1) Controller Bean (TestController.java) which is in RequestScoped (enterprise context) is called index_cut.xhtml, when we come for first time on this page.

enter image description here

2) On button “Load”, we load the following method to populate the sapFinancialPeriodList which works fine and displays the data

<<XHTML Code>>

<<JAVA Code>>

<<XHTML Code>>

3) After changing the content on the page and submitting, the sapFinancialPeriodList appears as NULL in the following method –

<<JAVA Code>>

<< XHTML Result >>

Any suggestions?

JoseK
  • 31,141
  • 14
  • 104
  • 131
  • The form submit at step 3 accounts basically sends a brand new HTTP request. And your bean is request scoped. Do you see it now ... ? – BalusC Nov 05 '12 at 17:53
  • @BalusC: We tried ConversationScoped too. I see the point on Request. What do you suggest? – JoseK Nov 05 '12 at 17:57

1 Answers1

2

Your bean is request scoped and you're loading the data model on action only instead of on (post)construction. When the HTTP response after the action which loaded the data is finished, then the bean is garbaged. The subsequent request would get a brand new instance of the bean with all properties set to default. However, as the same data model isn't been preserved during (post)construct, it remains empty.

In JSF2 you'd solve this with using @ViewScoped. This way the bean will live as long as you're interacting with the same view by postbacks (which return null or void).

In CDI you'd need to solve this using @ConversationScoped, which in turn requires some additional @Inject Conversation boilerplate, complete with begin() and end() calls at the right moments. For a concrete example, see also What scope to use in JSF 2.0 for Wizard pattern?.

An alternative is to pass the parameters responsible for creating the data model to the subsequent request via <f:param> in the command link/button as follows

<h:commandButton value="save" ...>
    <f:param name="period" value="#{bean.period}" />
</h:commandButton>

and then recreate exactly the same data model in (post)constructor of the request scoped bean as follows

String period = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("period");
List<SapFinancialPeriod> sapFinancialPeriodList = someservice.list(period);

(the above is by the way nicer to solve with @ManagedProperty if you were using standard JSF; as far as I know CDI doesn't have an annotation which enables you to set a HTTP request parameter as a bean property)

See also:


Unrelated to the concrete problem, the upcoming JSF 2.2 solves this functional requirement in a nicer way using the new "Faces Flow" feature with the new @FlowScoped annotation and the new xmlns:j="http://java.sun.com/jsf/flow" tags.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Nice answer. I can recommend looking into ViewAccessScoped rather then using ConversationScoped You can get it from Deltaspike in the next release or right now from myfaces codi. – Karl Kildén Nov 05 '12 at 20:11
  • Reqarding injecting http request parameter. I felt no answer covered it clean enough so I did a Q&A with it. http://stackoverflow.com/questions/13239975/depedency-inject-request-parameter-with-cdi/13239977#13239977 – Karl Kildén Nov 05 '12 at 20:38
  • @BalusC: It worked with conversationscoped - but the weird thing I'm seeing is if I keep RequestScoped and reload the bean with *original values from the DB in the PostConstruct* on submit, then the bean is able to hold and display the changed values from the screen. without use of f:param. This is peculiar to the ArrayList - so I tried creating an empty ArrayList in the Postconstruct for Submit, but it will not take new values from the screen in the submitdata(). It will only replace any existing values within the ArrayList, provided one such ArrayList is created in the Postconstruct. – JoseK Nov 07 '12 at 09:59
  • The submitted and local input values are stored in UI component tree state (which is by itself basically in the view scope). – BalusC Nov 07 '12 at 10:39