Binding attribute causes duplicate component ID found in the view
Asked Answered
T

2

14

Here is JSF code:

<h:inputText binding="#{bean.input}" />

And here is a part of backing bean for binding support:

private HtmlInputText input;

public void setInput(HtmlInputText input) {
    this.input = input;
}

public HtmlInputText getInput() {
    return this.input;
}

When I open page at first time everything works fine but when I open it at second time (refresh or open the same url in another tab or any other way) I get duplicate ID error. Error message says that <h:inputText> has no unique ID. Here is a part of long error message:

java.lang.IllegalArgumentException: Component ID formId:inputId has already been found in the view
    +id: inputId type: javax.faces.component.html.HtmlInputText@cafebabe

The problem occured after I added binding attribute. If I remove it, everything will work fine again. How do I properly use binding attribute?

Theoretics answered 20/1, 2010 at 13:49 Comment(0)
T
35

Duplicate component ID errors may occur when:

  • Same ID is used on different components inside the same NamingContainer.
  • Physically different components are bound to the same property of the same bean.
  • The <f:subview> is been declared in the include page instead of the parent page.
  • The same include page is included multiple times inside the same NamingContainer.
  • A component is been dynamically created without having an explicit ID assigned.

Here, NamingContainer is among others the <h:form>, <h:dataTable> and <f:subview>.

When using binding, you should bind it to a property which is used exclusively by the component in question on a per-request basis. Your specific case indicates that this binding is been shared by multiple components, perhaps across different requests. When you bind the component to a property of a backing bean, then the backing bean should absolutely not be in a broader scope than the request scope. See also JSF 2.0 specitication chapter 3.1.5 (emphasis mine):

3.1.5 Component Bindings

...

Component bindings are often used in conjunction with JavaBeans that are dynamically instantiated via the Managed Bean Creation facility (see Section 5.8.1 “VariableResolver and the Default VariableResolver”). It is strongly recommend that application developers place managed beans that are pointed at by component binding expressions in “request” scope. This is because placing it in session or application scope would require thread-safety, since UIComponent instances depends on running inside of a single thread. There are also potentially negative impacts on memory management when placing a component binding in “session” scope.

See also:

Tawnatawney answered 20/1, 2010 at 13:52 Comment(6)
Backing bean has session scope. This bean is being used only by this component. What do you mean saying 'exclusively'?Theoretics
Thus different requests/views inside the same session is sharing the same binding? This isn't always going to work as well. Put it in a request scoped bean.Tawnatawney
I'm going to avoid binding at all and find suitable workaround. But I just wonder is it normal binding behavior (i.e. from spec)? Will I get the same result with standard jsf components? Or it depends?Theoretics
Huh? Just put in request scope and use it further. You can even make it a child of the session scoped bean. Another cause can also be that the component is been used in an include/composition file and that it is included/reused multiple times inside the same page.Tawnatawney
Thanks for you list of possible problems. Its second item gave me an insight that getLineChartComponent() method should return null (in my case it doesn't break any functionality, I'm interested in setter method).Theoretics
Just for the records: there was a JSF bug (JAVASERVERFACES-4240) in JSF 2.2.12, which also caused a duplicate id exception. The issue was finally fixed in JSF 2.2.15. See also this SO question for details.Cereal
P
0

I had the same problem until found this tag that evit the duplicate component id

<f:subview id="top">
    <p:outputPanel id="panelHeader1"  
        binding="#{circularRequestBean.panelHeader}" autoUpdate="true"
        class="col-md-12 col-sm-12 col-xs-12 col-lg-12 wihtoutPadding"
        style="padding:0px; !important; display:block;" />

</f:subview>
Perpetua answered 16/11, 2017 at 17:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.