Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use component binding in JSF right ? (request-scoped component in session scoped bean)

Tags:

scope

jsf

jsf-2

Mojara 2.1.21

I've updated my question based on comments. I have two situation where a component is bound to server session bean. (Additional links with information: Binding attribute causes duplicate component ID found in the view and https://stackoverflow.com/a/12512672/2692917)

Version 1:

single.xhtml:

 <h:outputText value=... binding="#{mysessionbean.out}" />

java:

 @SessionScoped @Named public class Mysessionbean {
    UIOutput out;
    //getter and setter ....
 }

Version 2:

template.xhtml:

 <h:outputText value=... binding="#{mysessionbean.out}"

view1.xhtml:

 <ui:composition template="template.xhtml" />

view2.xhtml:

 <ui:composition template="template.xhtml" />

java:

 @SessionScoped @Named public class Mysessionbean {
    UIOutput out;
    //getter and setter ....
 }

Version 1 is ok. (At least I've not encounter any errors so far). But in version 2 the duplicate id error is occured if I navigate from one page to another. Why does it happen ? Is it safe to use (request-scoped) component (in version 1) with session scoped binding ? Are there another use cases to consider ?

Edit: Functional requirement 1:

I want to use Primefaces datatable in a view. I need some info from this datatable. (Such as selected row or row index). So binding the datatable helps me to retrieve this info.

Functional requirement 2:

Components binding in composite components. They will be bound to session scoped bean. (And used mainly on one page, but what if I used it on another page ?

Requirements 3

The situation as in "Version 2". Template with primefaces menu and session scoped binding. For this I've used the EL-Binding.

like image 269
John N Avatar asked Dec 26 '22 21:12

John N


1 Answers

In JSF 2.x, unless you want to manipulate components programmatically (which is at its own also rather fishy), there is no sensible real world use case to bind components to a backing bean. For sure not if they are further not been used in the backing bean itself, or if it are solely their attributes which are been flattened out.


As to the functional requirement of getting the current row of the data table, there are much better ways listed here, How can I pass selected row to commandLink inside dataTable?, for example if your environment supports EL 2.2:

<h:dataTable value="#{bean.items}" var="item">
    <h:column>
        <h:commandLink value="Foo" action="#{bean.foo(item)}" />

The two last requirements are totally unclear. At least, if you're doing something like:

<x:someComponent binding="#{bean.someComponent}" />

with in bean

someComponent.setSomeAttribute(someAttribute);
someComponent.setOtherAttribute(otherAttribute);

then you should instead be doing

<x:someComponent someAttribute="#{bean.someAttribute}" otherAttribute="#{bean.otherAttribute}" />

Or, if you intend to be able to use the component somewhere else in the view like so

<h:inputText ... required="#{not empty param[bean.save.clientId]}" />
...
<h:commandButton binding="#{bean.save}" ... />

and the instance is further nowhere been used in the bean, then just get rid of the unnecessary property altogether:

<h:inputText ... required="#{not empty param[save.clientId]}" />
...
<h:commandButton binding="#{save}" ... />

If there is really, really no way for some unclear reason, then split all request scoped properties of the session scoped bean out into a separate request scoped bean which you in turn bind to form actions. The session scoped one can just be injected as a @ManagedProperty of the request scoped one.


See also:

  • Binding attribute causes duplicate component ID found in the view
  • How does the 'binding' attribute work in JSF? When and how should it be used?
like image 168
BalusC Avatar answered Jan 29 '23 12:01

BalusC