3

I'm editing data with <p:dataTable> row editor as below.

<p:dataTable value="#{bean.users}" var="user" editable="true">
    <p:ajax event="rowEdit" listener="#{bean.onRowEdit}" />
    <p:ajax event="rowEditCancel" listener="#{bean.onRowEditCancel}" />
    <p:column>
        <p:cellEditor>
            <f:facet name="output">
                <h:outputText value="#{user.firstName}" />
            </f:facet>
            <f:facet name="input">
                <p:inputText value="#{user.firstName}" />
            </f:facet>
        </p:cellEditor>
    </p:column>
</p:dataTable>

The backing bean is implemented as below.

private List<User> users;

@EJB
private UserService userService;

public List<User> getUsers() {
    users = userService.list();
    return users;
}

When I enter the new data in the cellEditor and submit it, they are not available in listener method. I noticed that they get overwritten by the data called from the database.

Why does this happen and how can I avoid it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Tom C
  • 804
  • 2
  • 11
  • 24
  • 1
    You are implementing a very crucial/critical business logic in a getter method - `getAllUsers()`. This method will be called several times causing the extremely costly logic to be executed several times. Please consider moving this logic in its own place such as a method decorated by `@PostConstruct` (or consider using the PrimeFaces lazy data model associated with a ``. – Tiny Jan 12 '15 at 19:10
  • Which one is more efficient, using @PostConstruct or the lazy data model? I've done a quick skim on them both to see which one would be more effective & efficient. – Tom C Jan 12 '15 at 19:12
  • There is nothing about "*efficient*" (they are to be considered separately). Both are to be used depending upon the requirements. If you want to fetch a list of rows from a database in a page-wise manner (and you should always do it unless the list is of limited size containing only a few rows in some situations), you can use the lazy data model. – Tiny Jan 12 '15 at 19:18

1 Answers1

5

Your problem is caused by performing business logic in a getter method. Every iteration over the data table will invoke the getter method. So, while JSF is busy iterating over the data table in order to set the submitted values in the model, the getter calls returns a new list from DB again and again.

You're not supposed to perform business logic in a getter method. As long as you're a starter, you'd better refrain from touching the getter (and setter) methods and perform the job elsewhere in an one time called method.

You likely need a @PostConstruct (and a true service/DAO class) here:

private List<User> users;

@EJB
private UserService userService;

@PostConstruct 
public void init() {
    users = userService.list(); // Call the DB here.
}

public List<User> getUsers() {
    return users; // Just return the already-prepared model. Do NOT do anything else here!
}

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555