Search code examples
jsfprimefacesdatatableprimefaces-datatable

Primefaces datatable used to display non updateable database view results?


Good day

Is it possible (I seem to be stuck at not being able to click the 'tick' to accept a row edit) to use a Primefaces datatable to display the result of a non updateable Postgres view, but have custom code in the onRowEdit event that will persist the changes correctly to the DB?

Or MUST a Primefaces / JSF datatable be linked to an updateable entity mapping in order for it to be used to 'update' and display info?

I have in the .xhtml file this:

 <p:dataTable id="conf_data_table" var="confRoomBookingDisplay" style="width: auto" rowIndexVar="rowid" editingRow="true"
                             value="#{conferenceRoomBookingView.conferenceRoomBookingList}" editable="true"
                             editMode="row" widgetVar="cellBookings">
                    <f:facet name="header">
                        Venue Booking
                    </f:facet>

                    <p:ajax event="rowEdit" listener="#{conferenceRoomBookingView.onRowEdit}"
                            update=":create_new_booking:growl"/>
                    <p:ajax event="rowEditCancel" listener="#{conferenceRoomBookingView.onRowCancel}"
                            update=":create_new_booking:growl"/>

                    <p:column headerText="Booking Ref" style="width: 10%; text-align: center">
                        <p:outputLabel value="#{ConferenceRoomBooking.conferenceRoomBookingAid}"
                                       style="text-align: center"/>
                    </p:column>

                    <p:column headerText="Time Slot" style="width: 10%; text-align: center">
                        <p:outputLabel value="#{ConferenceRoomBooking.timeSlot}" style="text-align: center"/>
                    </p:column>

                    <p:column headerText="Booked For" style="width: 15%; alignment: center">
                        <p:outputLabel value="#{ConferenceRoomBooking.empShortNameSurname}"
                                       style="text-align: left"/>
                    </p:column>


                    <p:column headerText="Booking Comment" style="width: 60%; alignment: center">
                        <p:cellEditor>
                            <f:facet name="output">
                                <h:outputText value="#{ConferenceRoomBooking.conferenceRoomBookingComment}"/>
                            </f:facet>
                            <f:facet name="input">
                                <p:inputText value="#{ConferenceRoomBooking.conferenceRoomBookingComment}"
                                             style="width:98%"/>
                            </f:facet>
                        </p:cellEditor>
                    </p:column>

                    <p:column style="width: 5%">
                        <p:rowEditor />
                    </p:column>

                </p:dataTable>

And then on my @RequestScoped (javax.enterprise.context.RequestScoped) @Named backing bean (I tried it with a @ViewScoped - org.omnifaces.cdi annotation as well).

The event code looks like this:

public void onRowEdit(RowEditEvent event) {
    conferenceRoomBookingAid = (((ConferenceRoomBookingEntity) event.getObject()).getConferenceRoomBookingAid());
    String msgEdit = Long.toString(conferenceRoomBookingAid);
    FacesMessage msg = new FacesMessage("Booking Edited for Reference ID:", msgEdit);
    FacesContext.getCurrentInstance().addMessage(null, msg);
    confRoomService.persistComment(How do I get my updated value from the event???);
}

public void onRowCancel(RowEditEvent event) {
    conferenceRoomBookingAid = (((ConferenceRoomBookingEntity) event.getObject()).getConferenceRoomBookingAid());
    String msgEdit = Long.toString(conferenceRoomBookingAid);
    FacesMessage msg = new FacesMessage("Booking Cancelled for Reference ID: ", msgEdit);
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

Currently commenting out the confRoomService.persistComment(How do I get my updated value from the event???); code, gets me to a properly rendered table where I am able to edit the row. The problem however is that I can not click the 'accept' / 'yes' tick with the mouse, and pressing enter just clears the cell again.

The reason I am using a non updateable view is that the current DB structure uses foreign keys to link the data to persons, and using the base entity will display the foreign key id instead of its value.


Solution

  • After a lot of different versions of Entities and database views, I came to the conclusion that the JSF / Primefaces datatable component is meant to be used:

    1. When linked directly via an Entity that is mutable, and thus a 100% representation of the underlying database table, with no custom views of the data, full editing is allowed and works as advertised.
    2. When linked to an Entity that is based on a Database View (updateable or not), the cells / rows of the datatable cannot be edited in the datatable cellEdit or rowEdit events.

    I would be ecstatic if proved wrong on the above, but for now have made peace with using the datatable as immutable when based on a database view.