On a Liferay plugin project I've got a JSF+PF based portlet on which I've created a minimal, complete, and verifiable example dealing with <p:dataTable>
and <p:rowExpansion>
elements which are working weirdly. The code is the one as follws:
.xhtml side:
<h:form id="entityGuidesForm">
<p:panel>
<p:dataTable value="#{bean.items}" var="item">
<p:column style="width:15px">
<p:rowToggler />
</p:column>
<p:column headerText="name">
<h:outputText value="#{item}" />
</p:column>
<p:rowExpansion>
<p:dataTable value="#{bean.subitems}" var="subitem">
<p:column headerText="subname">
<h:outputText value="#{subitem}" />
</p:column>
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
</p:panel>
</h:form>
That is, a date table displaying some rows, each row showing a nested table.
bean side:
@ManagedBean(name = "bean")
@ViewScoped
public class Bean implements Serializable {
private static Logger logger = Logger.getLogger(Bean.class);
private String[] items;
private String[] subitems;
public Bean() {
logger.trace("bean created");
}
@PostConstruct
private void onPostConstruct() {
logger.trace("start");
try {
items = new String[1];
items[0] = "0";
subitems = new String[1];
subitems[0] = "0.1";
}
catch (Exception e) {
e.printStackTrace();
}
}
public String[] getItems() {
logger.trace("start");
return this.items;
}
public void setItems(String[] items) {
logger.trace("start");
this.items = items;
}
public String[] getSubitems() {
logger.trace("start");
return this.subitems;
}
public void setSubitems(String[] subitems) {
logger.trace("start");
this.subitems = subitems;
}
When the page containing that portlet gets rendered, the logger throws this log:
[TRACE] Bean:<init>():bean created
[TRACE] Bean:onPostConstruct():start
[TRACE] Bean:getItems():start
[TRACE] Bean:getItems():start
Although it seems weird to me that the getItems()
method is called two times, the weirdest thing comes when I click on the <p:rowToggler />
element, getting this log:
[TRACE] Bean:getItems():start
... //15 times as the previous line, 17 times overall
[TRACE] Bean:getItems():start
[TRACE] Bean:getSubitems():start
[TRACE] Bean:getSubitems():start
[TRACE] Bean:getItems():start
[TRACE] Bean:getItems():start
I don't know why the getItems()
method is called 17 times before the getSubitems()
method is called. It's not a major problem on this example, but in my real example the getItems()
method implies accesing a database and I would like to avoid it as much as I can.
Any clarification on what's happening would be appreciated, as well as a possible solution. Thanks.