p:datatable selection problem after upgrade to PF 5.2 RC

UI Components for JSF
rider
Posts: 497
Joined: 05 Mar 2010, 13:17

24 Mar 2015, 20:47

Dear all,

After the upgrade to 5.2 RC I got the folliwing issue for the datatable which has a selection:
java.lang.UnsupportedOperationException: getRowData(String rowKey) must be implemented when basic rowKey algorithm is not used.
Please find attached my code:


XHTML Page

Code: Select all

<p:dataTable id="jobListDatatable"
						value="#{jobRequestController.lazyModel}" var="job"
						rowKey="#{job.id}" widgetVar="jobTable"
						filteredValue="#{jobRequestController.filteredJob}"
						selection="#{jobListController.selectedJobList}" rows="10"
						pageLinks="10" paginatorPosition="bottom" lazy="true"
						paginator="true" resizableColumns="true"
						currentPageReportTemplate="(Eintrag: {startRecord}-{endRecord} von {totalRecords}, Seite: {currentPage} von {totalPages})"
						paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
						rowsPerPageTemplate="10,20,50,100" paginatorAlwaysVisible="false"
						emptyMessage="Keine Job gefunden">

						<f:facet name="header">
							<p:outputPanel style="float:left;">
								<p:commandButton value="Job anlegen"
									action="#{jobListController.doAddJob}" icon="fa fa-floppy-o"
									styleClass="btn-success" style="text-align:left" />

								<p:commandButton ajax="true" process="@all" style="float:right"
									disabled="#{jobListController.selectedJobList.size() != 1}"
									icon="fa fa-files-o" styleClass="btn-success" title="Kopieren"
									onclick="PF('dlgCopyJob').show()" />
								<h:outputText value="&#160;" />
								<p:commandButton onclick="PF('deleteJobDialog').show()"
									style="float:right" styleClass="btn-danger"
									disabled="#{jobListController.selectedJobList.size() != 1}"
									icon="fa fa-trash-o" title="Löschen"
									actionListener="#{jobListController.doDeleteJob(job)}" />
								<h:outputText value="&#160;" />
								<p:commandButton id="toggler" type="button" style="float:right"
									icon="fa fa-ellipsis-h" styleClass="btn-warning" />
								<p:columnToggler datasource="jobListDatatable" trigger="toggler" />

							</p:outputPanel>

							<p:outputPanel style="text-align: right;">
								<p:inputText id="globalFilter" onkeyup="PF('jobTable').filter()"
									style="width:200px" />
								<p:watermark for="globalFilter" value="Suche..." />
								<h:outputText value="&#160;" />
								<p:commandButton ajax="true" styleClass="btn-info"
									title="#{msg['general.button.extendedSearch']}"
									icon="fa fa-search-plus" update=":jobListForm"
									actionListener="#{jobRequestController.doShowExtendedSearch}" />
							</p:outputPanel>

						</f:facet>

						<p:ajax event="rowSelect" update="jobListDatatable" />

						<p:ajax event="rowUnselect" update="jobListDatatable" />

						<p:ajax event="rowSelectCheckbox" update="jobListDatatable" />

						<p:ajax event="rowUnselectCheckbox" update="jobListDatatable" />

						<p:column selectionMode="multiple" toggleable="false"
							style="width: 35px; text-align: center;" />


						<p:column sortBy="#{job.jobName}" filterBy="#{job.jobName}"
							filterStyle="display:none">
							<f:facet name="header">
								<h:outputText value="Name" />
							</f:facet>
							<p:commandLink
								action="#{jobListController.redirectToOverviewPage(job)}"
								ajax="false" style="margin-right:20px;">
								<h:outputText value="#{job.jobName}" />
							</p:commandLink>
						</p:column>
						
					</p:dataTable>


Bean

Code: Select all

@ViewScoped
@Named
public class JobRequestController extends ListDataModel<Job> implements
		SelectableDataModel<Job>, Serializable {

	private static final long serialVersionUID = 2815796004558360299L;
	private static final Logger LOGGER = LoggerFactory
			.getLogger(JobRequestController.class);

	@Inject
	private LoginBean loginBean;

	@RequestScoped
	private List<Job> filteredJob;

	private LazyDataModel<Job> lazyModel;

	@SuppressWarnings("serial")
	@PostConstruct
	public void findAllJobByUserId()
			throws SearchRememberNotFoundException {

		lazyModel = null;

		if (lazyModel == null) {
			lazyModel = new LazyDataModel<Job>() {

				@Override
				public List<Job> load(int startingAt, int maxPerPage,
						String sortField, SortOrder sortOrder,
						Map<String, Object> filters) {
					Long loginUserId = loginBean.getCurrentUser()
							.getId();
					List<Job> list = null;

					try {
						list = jobService.findAllJobLazyLoading(
								loginMandatoryId, startingAt, maxPerPage,
								sortField, sortOrder, filters);

						lazyModel.setRowCount(list.size());
					} catch (JobNotFoundException e) {
						lazyModel.setRowCount(0);
					} catch (NullPointerException e) {
						lazyModel.setRowCount(0);
					}
					return list;
				}

			};
		}
	}

	@Override
	public Job getRowData(String rowKey) {
		List<Job> jobs = (List<Job>) getWrappedData();

		for (Job job : jobs) {
			if (job.getId().equals(rowKey))
				return job;
		}
		return null;
	}

	@Override
	public Object getRowKey(Job job) {
		return job.getId();
	}
Bean which includes the List for selected Items:
@ViewScoped
@Named
public class JobListController implements Serializable {

private List<Job> selectedJobList;
// getter + setter

Entity:

Code: Select all

	

....

@Entity
@Table(name = "job")
public class Job implements Serializable {

.....

@Id
	@GeneratedValue(generator = "job_id_seq", strategy = AUTO)
	@SequenceGenerator(name = "job_id_seq", sequenceName = "job_job_id_seq", allocationSize = 1)
	@Column(name = "job_id", nullable = false)
	private Long id = NO_ID;
Could you help me, please.
I saw there is also another user which has this problem:
http://forum.primefaces.org/viewtopic.php?f=3&t=41421

Thank you very much.
Best Regards
Primefaces 12.0, WildFly 21

tandraschko
PrimeFaces Core Developer
Posts: 3979
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

24 Mar 2015, 21:51

the rowKey attribute should NOT be used with lazy loading. As the exception says, overwrite getRowData and getRowKey in your LazyDataModel.
Thomas Andraschko

PrimeFaces | PrimeFaces Extensions

Apache Member | OpenWebBeans, DeltaSpike, MyFaces, BVal, TomEE

Sponsor me: https://github.com/sponsors/tandraschko
Blog: http://tandraschko.blogspot.de/
Twitter: https://twitter.com/TAndraschko

rider
Posts: 497
Joined: 05 Mar 2010, 13:17

24 Mar 2015, 22:22

You mean: delete rowKey="#{job.id}" from my p:datatable?
The getRowData() and getRowKey() is already overwritten like in my first post.

Here I delete the rowKey="#{job.id}

Code: Select all

<p:dataTable id="jobListDatatable"
                  value="#{jobRequestController.lazyModel}" var="job".....>
I try to delete rowKey="#{job.id}.

Without rowKey="#{job.id}
But afterwards I got the error if I open the page. (So the page and datatable doesn´t appear)

With rowKey="#{job.id}
I got the error just after selecting a row.

The same error message:
Caused by: java.lang.UnsupportedOperationException: getRowKey(T object) must be implemented when basic rowKey algorithm is not used.
So I have no idea. In PF 5.1 everything is ok.
Primefaces 12.0, WildFly 21

tandraschko
PrimeFaces Core Developer
Posts: 3979
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

24 Mar 2015, 22:24

Check the abstract LazyDataModel:
public T getRowData(String rowKey) {
throw new UnsupportedOperationException("getRowData(String rowKey) must be implemented when basic rowKey algorithm is not used.");
}

public Object getRowKey(T object) {
throw new UnsupportedOperationException("getRowKey(T object) must be implemented when basic rowKey algorithm is not used.");
}

If you overwrite it, the exception can't occur anymore.
Thomas Andraschko

PrimeFaces | PrimeFaces Extensions

Apache Member | OpenWebBeans, DeltaSpike, MyFaces, BVal, TomEE

Sponsor me: https://github.com/sponsors/tandraschko
Blog: http://tandraschko.blogspot.de/
Twitter: https://twitter.com/TAndraschko

rider
Posts: 497
Joined: 05 Mar 2010, 13:17

24 Mar 2015, 23:08

I change it now to
public class JobRequestController extends LazyDataModel<Job> implements
SelectableDataModel<Job>, Serializable
The methods was already annotated with @Override.
=> But I got the same error message :?
Primefaces 12.0, WildFly 21

tandraschko
PrimeFaces Core Developer
Posts: 3979
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

24 Mar 2015, 23:30

jobRequestController.lazyModel is the datamodel which should implement this methods, not jobRequestController itself.
Thomas Andraschko

PrimeFaces | PrimeFaces Extensions

Apache Member | OpenWebBeans, DeltaSpike, MyFaces, BVal, TomEE

Sponsor me: https://github.com/sponsors/tandraschko
Blog: http://tandraschko.blogspot.de/
Twitter: https://twitter.com/TAndraschko

rider
Posts: 497
Joined: 05 Mar 2010, 13:17

25 Mar 2015, 21:46

Okay, this works.

BUT:
If I select a column -> the column is 0,2 seconds selected and afterwards the column is unselected.

I have the following code if a column is selected:

Code: Select all

<p:ajax event="rowSelect"  update="jobListDatatable"/>
						<p:ajax event="rowUnselect"  update="jobListDatatable"/>
						<p:ajax event="rowSelectCheckbox"  update="jobListDatatable"/>
						<p:ajax event="rowUnselectCheckbox"  update="jobListDatatable"/>
If I delete update="jobListDatatable" than this error does not appear.
But I need to update my p:datatable because I have some buttons which should only enable if a column is selected.

But I don´t know-> Between 5.1 and 5.2 something was changed in the code directly for the lazy and selectable columns.
Currently this is a showstopper to migrate to 5.2 for me. I have many of p:datatables. This is moreless one day for me to adjust all this datables.
I don´t know how many people test 5.2 RC already. But in another forum post there was also recomended moreless the same issue.
Could you check it again, please.
Thank you very much.
Primefaces 12.0, WildFly 21

tandraschko
PrimeFaces Core Developer
Posts: 3979
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

26 Mar 2015, 00:03

we changed that part by design cause the rowKey attribute handling with a LazyDataModel is not correct.

Lazy loading and selection works fine in the showcase with 5.2.RC1.
Thomas Andraschko

PrimeFaces | PrimeFaces Extensions

Apache Member | OpenWebBeans, DeltaSpike, MyFaces, BVal, TomEE

Sponsor me: https://github.com/sponsors/tandraschko
Blog: http://tandraschko.blogspot.de/
Twitter: https://twitter.com/TAndraschko

rider
Posts: 497
Joined: 05 Mar 2010, 13:17

26 Mar 2015, 21:17

hm any user which implement this also with rowKey should now adjust his code? :shock:
If I have in this case some improvements I would say ok. But I can´t see in this case any improvements.
In my opinion this is not very userfriendly. If I would have 5-10 p:datatable than ok, I would change the code.
But I have to adjust +/- 50 p:datatable. This are 3 days only for adjust this code.

It´s the same like the adjustments for PF('.....') in I guess it was in version PF 3 to PF 4.0 version.

Did you check also the update in the <p:ajax events?

Code: Select all

<p:ajax event="rowSelect"  [b]update="jobListDatatable"[/b]/>
Primefaces 12.0, WildFly 21

tandraschko
PrimeFaces Core Developer
Posts: 3979
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

31 Mar 2015, 14:55

If you would check the old user guides, a example with lazy loading never used the rowKey attribute.

check e.g. the 4.0 userguide:
Also you must implement getRowData and getRowKey if you have selection enabled.
We just added a check now, that rowKey can't not be used mistakenly.
Thomas Andraschko

PrimeFaces | PrimeFaces Extensions

Apache Member | OpenWebBeans, DeltaSpike, MyFaces, BVal, TomEE

Sponsor me: https://github.com/sponsors/tandraschko
Blog: http://tandraschko.blogspot.de/
Twitter: https://twitter.com/TAndraschko

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 27 guests