users@woodstock.java.net

Re: Data Provider for Table

From: Quintin Beukes <quintin_at_last.za.net>
Date: Sat, 26 Jul 2008 23:30:35 +0200

Even if you can give me an alternative way of retrieving the object
and managing the data.

A data provider and fetching the row's object, updating it and then
saving it is the best way I can think of.

Alternative i can add a hidden field to the row that carries the
primary key of the row's item, fetching this from the database, and
update/merge it is another way. But I would like to avoid this as it
strays away from the whole abstraction of the web layer pattern JSF
creates, and returns you to the standard web programming design
pattern.

Quintin

On Sat, Jul 26, 2008 at 11:15 PM, Quintin Beukes <quintin_at_last.za.net> wrote:
> Hey,
>
> I have a very odd, but very real problem, and unless I understand/use
> this wrong, is a problem in the general design of woodstock.
>
> Lets say I'm using a PostgreSQL (because it needs different techniques
> to be reproduced for different DBs) table "users", and it looks like
> this
>
> id | name
> 1 | John
> 2 | Joe
>
> Then I have a managed bean "ManageUsers", and a JSF page
> "ManageUsers". Inside this page I have a "<webuijsf:table>" and
> "<webuijsf:tableRowGroup sourceData='#{ManageUsers.olUsers}'", where
> olUsers is an ObjectListDataProvider instance variable of the
> ManageUsers managed bean.
>
> In the table, each row has a text field for the "name", and an update
> button which updates that specific row. So inside the action method
> for this button, I do the update logic. To do this I retrieve the
> object with the olUsers.getObject(rowKey), update it's values with
> those in the textfield (ie. name) and then "merge" it using my
> facade's EntityManager.merge() method.
>
> This all works fine, but there's a catch.
>
> Since the instance variable isn't "remembered" between requests, I
> have to "refresh" it's data, ie. read it from the database again, and
> then only can I do getObject(). Also, the getObject() method fetches
> the object, based on the row number. So if you update the second row,
> then it will fetch the second record retrieved from the database. So
> if the natural ordering of the rows changes, or a row comes in between
> when using fixed ordering, and the row you updated has it's position
> changed, then you will update the wrong row.
>
> So for the above example dataset, load the page and change the name
> for the user in the 2nd row, ie. joe. Then go into the database
> separately, and update the first row. This means PostgreSQL will now
> list the data like so:
> id | name
> 2 | Joe
> 1 | John
>
> Go back to the page and click the update button. it's trying to update
> the row with index 1, so since the data is refreshed using the new
> ordering, you're actually updating John, instead of the intended Joe.
>
> The only way to get around this is to store the data provider in the
> session, which isn't ideal, because for a large project like mine, the
> session object is going to become cluttered with hundreds of data
> providers.
>
> But developer comfort isn't a real problem. User experience is. And
> when storing the data in the session might cause problems when the
> same user has 2 windows open, since both windows will be using the
> same session right? Some might argue that this isn't a problem, as the
> same data set is represented, but the same problem regarding ordering
> will be experienced this way.
>
> Can anyone tell me how to get around this?
> --
> Quintin Beukes
>



-- 
Quintin Beukes