JoseK
JoseK

Reputation: 31371

CDI bean List in datatable is null on submit from JSF

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?

Upvotes: 0

Views: 964

Answers (1)

BalusC
BalusC

Reputation: 1109645

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.

Upvotes: 2

Related Questions