Reputation: 2332
Suppose you have bean which holds cars table model, let's call this bean carManager. Let's assume that there exists another bean, which can take cars table model element and get proper translation based on selected language, let's call that bean carProcessor. So, now we can make a data table like this:
<p:dataTable var="car" value="#{carManager.tableModel}">
<p:column headerText="Car name" sortBy="#{carProcessor.getCarTranslateByLanguageId(car.data, carManager.selectedLanguage.id).name}">
<h:outputText value="#{carProcessor.getCarTranslateByLanguageId(car.data, carManager.selectedLanguage.id).name}"/>
</p:column>
<p:column headerText="Description" sortBy="#{carProcessor.getCarTranslateByLanguageId(car.data, carManager.selectedLanguage.id).description}">
<h:outputText value="#{carProcessor.getCarTranslateByLanguageId(car.data, carManager.selectedLanguage.id).description}"/>
</p:column>
</p:dataTable>
This is the structure of car object:
public class Car{
List<Translation> translation = new ArrayList<Translation>();
public List<Translation> getTranslation()
{
return translation;
}
public void setTranslation(List<Translation> translation)
{
this.translation = translation;
}
}
Here is translation class:
public class Translation{
private name = "";
private description = "";
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getDescription()
{
return this.description;
}
public void setDescription(String description)
{
this.description = description;
}
}
There was discussion going on http://forum.primefaces.org/viewtopic.php?f=3&t=33892&start=10 , and it seems that my row sorting should work, but it doesn't. As soon as I try to open that page, null pointer exception shows up.
Here is my stack trace:
org.apache.myfaces.view.facelets.el.ContextAwareELException: javax.el.ELException: java.lang.NullPointerException
org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.getValue(ContextAwareTagValueExpression.java:104)
javax.faces.component._DeltaStateHelper.eval(_DeltaStateHelper.java:266)
org.primefaces.component.column.Column.getSortBy(Column.java:95)
org.primefaces.component.datatable.DataTableRenderer.encodeColumnHeader(DataTableRenderer.java:325)
org.primefaces.component.datatable.DataTableRenderer.encodeThead(DataTableRenderer.java:595)
org.primefaces.component.datatable.DataTableRenderer.encodeRegularTable(DataTableRenderer.java:247)
org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:211)
org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:83)
javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:665)
javax.faces.component.UIData.encodeEnd(UIData.java:1704)
org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:74)
org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:57)
org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:72)
org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:57)
org.primefaces.extensions.component.layout.LayoutPaneRenderer.encodeBegin(LayoutPaneRenderer.java:152)
javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:587)
javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:517)
javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:541)
It turned out that
sortBy="#{carProcessor.getCarTranslateByLanguageId(car.data, carManager.selectedLanguage.id).name}"
carProcessor method getCarTranslateByLanguageId gets argument car.data as null. This is where null pointer exception comes from, even though
<h:outputText value="#{carProcessor.getCarTranslateByLanguageId(car.data, carManager.selectedLanguage.id).name}"/>
works as expected. How can I fix that?
There is opinion that
sortBy="#{carProcessor.getCarTranslateByLanguageId(car.data, carManager.selectedLanguage.id).name}"
and
<h:outputText value="#{carProcessor.getCarTranslateByLanguageId(car.data, carManager.selectedLanguage.id).name}"/>
are rendered at the different times so this is why car.data is allways null when passing to the carProcessor.getCarTranslateByLanguageId method and this is why it is not the null then simply printing value out in column.
Upvotes: 1
Views: 3674
Reputation: 2332
I managed to solve it by adding getTranslatedName() and getTranslatedDescription() in the Car class. It's because you can't pass arguments from list to sortBy="". So basically you need to call class which is responsible for language management inside the getTranslatedName() and getTranslatedName() methods and then check all translations, then return final value, so from now on my sortBy looks like this:
<p:column headerText="Car name" sortBy="getTranslatedName">
<h:outputText value="#{car.getTranslatedName}"/>
</p:column>
Upvotes: 1