4 Replies Latest reply on Aug 1, 2006 7:59 AM by bfo81

    How to update @DataModel and its ListDataModel?

    bfo81

      I have an Entity Person (my favorite example *g*) and a page that lists all instances.

      Here are some code snippets, believe me, it's simple ;).

      The class delivering the list:

      @Stateful @Scope(ScopeType.SESSION) @Name("personList")
      public class ....
      ...
       @DataModel
       private List<Person> persons;
      
       @Factory("persons")
       @Observer("personChanged")
       public void loadList() {
       person = em.createQuery("from Person");
       log.info("Persons are: " + persons);
       }
      ...
      


      The JSF:
      ...
      <h:dataTable var="person" value="#{persons}">
       ....
      </h:dataTable>
      



      Well, whenever a person is changed, added or deleted, the "personChanged" event is fired. This works perfectly, since the log always shows that really the newest state of all persons has been fetched from the database. If I just changed "John Doe" to "John Sixpack" then the change is shown in the persons variable immediately.

      BUT: The underlying ListDataModel (@DataModel wraps the java.util.List into a org.jboss.seam.jsf.ListDataModel) is only up to date after deleting or adding a Person, namely changing the number of all entries. If I change an existing Person then the ListDataModel doesn't change and the overview page shows the old status.

      So the List is up to date, the ListDataModel isn't (I found this out by adding a toString() method to ListDataModel that shows the wrapped data und outputting it via <h:outputText value="#{persons}" />).

      QUESTION:
      * How can I tell the ListDataModel that it should update its wrapped data?
      * Why does this only work automatically when changing the length of a list? (I'm curious ;))


        • 1. Re: How to update @DataModel and its ListDataModel?
          bfo81

          EDIT:

          person = em.createQuery("from Person");

          should be

          persons = em.createQuery("from Person");

          with an "s", of course ;).

          I wish there would be an edit function here ^^.

          • 2. Re: How to update @DataModel and its ListDataModel?

            Because the datamodel uses the object.equals() method to check whether the object has changed.

            I fell foul of this as well.

            Implement a more thorough equals expression, and datamodel should then realise it needs to push the information out to jsf.

            Hope this helps,

            James

            • 3. Re: How to update @DataModel and its ListDataModel?
              bfo81

              FOUND THE SOLUTION!

              DataModelBinder.isDirty(): This method compares the DataModelList's List with the List annotated by @DataModel to determine if the wrapped List has changed.

              And how are two lists compared? list1.equals(list2). This happens by first comparing the sizes of both lists and, if they are equal, comparing the elements pairwise by calling their equals() method.

              And that's the point: My equals() method implemented in the Person class just compared the class and getId(), but not the contents of the Person. Maybe this is where the @Version annotation could come into play ;).

              Maybe this is helpful for someone who runs into the same problem ;).

              • 4. Re: How to update @DataModel and its ListDataModel?
                bfo81

                @js8523: Thanks for your help. I started writing my post before your answer was there.