> Why are you all under the impression that forceIdIndexFormula pulls
> out all rows of the database again?
>
> I haven't implemented it - that was Sylvain, maybe he can shed some
> light on this issue - but I would suspect it goes to the database to
> fetch exactly the row that is indicated by this id.

How could it? The code that originally gets the data from the database is application specific, so too would be the code that grabs an individual object from the database. Right? I mean, that's my assumption. I don't see how the datatable code would know how to do that. (And this assumes you're actually working with a "classic" database)

> Another thing you can do with the extended data table is to set the
> preservedDataModel attribute to "true".
>
> With this, the dataModel of the list is serialized to the client (in
> the component state) and will be used for all phases on the postback
> until rendering response comes into place - then the new data-model
> will be fetched from the database.

You mean the entire dataModel object, and the wrapped data, is serialized?

> I wonder what your solution would be? I mean - you have to store the
> information at some place if you don't want to go back to the
> database?

I was thinking about this. The trouble is that I'm pretty new, so I'm not sure what way to go with it. Were I to choose as Vadar did (ie. the quick and easy path), I was thinking of the following:

- Add yet another attribute to the extended data table. This is el pointing to a bean method that sets the selected id

- When the user clicks, if both forceIdIndexFormula and this id setting method are defined, the datatable implementation just sets the id value. It *DOES NOT* set the current selected row in the DataModel

- The user then has to handle the data retrieval directly

Pros:

- The page can be coded without this "hack" to start, and if that particular page is flagged as being hit often, or many list entries, performance can be improved by this method being added. Minimal code change and no visible differences

- Improved performance (again, assumption)

Cons:

- "Hacky"

- Breaks the concept of the DataModel object

- As I said I'm new, so I don't know what this does to the rest of the event model, etc.

As I've also said in some of the various posts associated with this, a different component might make sense for this. You know? Maybe the component we use for linking from a list and the component used for editing a table of data shouldn't be the same component? Maybe datatable is being stretched too far?

Maybe I should really work with JSF for a little longer before I say things like that. However, I just feel like I'm trying too hard to do a list of links. That's all.

Thanks again,

-Kevin

Martin Marinschek wrote:
Why are you all under the impression that forceIdIndexFormula pulls
out all rows of the database again?

I haven't implemented it - that was Sylvain, maybe he can shed some
light on this issue - but I would suspect it goes to the database to
fetch exactly the row that is indicated by this id.

Another thing you can do with the extended data table is to set the
preservedDataModel attribute to "true".

With this, the dataModel of the list is serialized to the client (in
the component state) and will be used for all phases on the postback
until rendering response comes into place - then the new data-model
will be fetched from the database.

So if you enqueue an action and wander off to the detail page, the
data will not be fetched again. Caveat: the dataModel is serialized to
the client. If you don't like the memory wasted in your session in the
meantime, this is a fair solution.

I wonder what your solution would be? I mean - you have to store the
information at some place if you don't want to go back to the
database?

regards,

Martin

On 8/30/05, CONNER, BRENDAN (SBCSI) <[EMAIL PROTECTED]> wrote:

Sorry, not much time to "converse" today.  Just to point out that, when
using the example in O'Reilly last November for our own application, I
encountered a problem, and I banged my head against the wall for a few
days, and I even logged a PMR with IBM, thinking it was a bug in their
code.  IBM responded by pointing out that the "setWrappedData()" line
should be inside the "if" statement, and, when we made that change, our
code worked.  I haven't looked at it much since then, though, since we
haven't really encountered any more errors in our application (that
we've found, anyway!).  I just wrote a note in my book so I don't repeat
that error.

- Brendan

-----Original Message-----
From: Kevin Galligan [mailto:[EMAIL PROTECTED]
Sent: Tuesday, August 30, 2005 11:41 AM
To: MyFaces Discussion
Subject: Re: Concerning DataModel usage plus overhead?


I'm not so sure that's a "bug".  Please take a look at the code again.
I think it gets at the root of my problem.  In order for that to be a
bug, 'getSortedReportsModel' is also a bug.

 public DataModel getSortedReportsModel() {
        if (reportsModel == null) {
            reportsModel = new ListDataModel();
        }
        List reports = getReports();
        sortReports(reports);
        reportsModel.setWrappedData(reports);
        return reportsModel;
    }

Has to be changed to...

public DataModel getSortedReportsModel() {
        if (reportsModel == null) {
            reportsModel = new ListDataModel();
            List reports = getReports();
            sortReports(reports);
            reportsModel.setWrappedData(reports);
        }

        return reportsModel;
    }

Once you do that, however, the sorting links stop working, so we change
it to something like...

public DataModel getSortedReportsModel() {

        //This is a little shady, but we're just calling the function
to do the initialization
        reportsModel = getReportsModel();
        List reports = (List) reportsModel.getWrappedData();
        sortReports(reports);

        return reportsModel;
    }

Ok, so now the report list works, and you can sort it.  Great.  So,
somebody adds a report.  How do you see it?  Browser refresh?  No.
Click sort?  Doesn't show.  Click the actual refresh button?  Nope.  The

refresh button just returns "Refresh", which will simply reshow the
page.  Now we have to go in, code a function to dump and refresh the
DataModel, or at least the wrapped data.

*Note* The screen I'm talking about is "Chapter 10" > " Report List
Area, stage 3 (Example 10-3)".

My point is that I understand this enough to figure out how to make it
work, but I feel like I'm working around the implementation.  There are
several places in here where one can get into trouble.  I would consider

myself an advanced web application developer.  I'd be afraid to see what

somebody who didn't know too much about the medium does with this model.

 Especially if they are trying to point and click their way through it.

 That's what I'm concerned with.

Now, I also have the JSF In Action book.  This morning I came in and
planned on getting the Project Track example up and running to further
illustrate my point.  However, that thing is absolutely filled with
bugs.  For example, on the inbox, sort the table.  Then click an entry.
 It grabs the entry by index, but on the *unsorted* table.  You don't
even need to break that table with external data entry.  It'll break
itself.

I mean, I'm not trying to knock JSF or anybody that is trying to help me

with an answer.  I guess I'm trying to point out something that I think
could be very error prone if in the wrong hands, and that might be
implemented better.  I'd certainly like to find an implementation that
was a little "better".  Better being a subjective opinion.

The extended data table in myfaces allows for the forceIdIndexFormula,
which will link by id value, which will keep things consistent with
these examples.  Even the "bug" above will work fine with
forceIdIndexFormula specified.  Back to my original post, however, as
compared with the "classic" link-by-id pattern, the
'forceIdIndexFormula' does significantly more work than it needs to.  By

that I mean I assume its going to the database to pull back all rows
again, then scanning through each to find the id value selected.

I'll leave this alone for now.  I'm fixating.  I guess I still don't
understand why nobody else seems to have this issue.  As a "real world"
example, the way I found this was working on the webapp for jboss's jbpm

component.  It uses jsf, which is why I started learning jsf.  This
problem is in several key places in that app.  By way of example, the
task list.  The application is a workflow processor.  I'd assume that
correct tasklist functionality is important.  The task page just shows a

list of tasks.  Hitting refresh should show you the current list of
tasks, which it does.  The problem is that if a new task is added after
you've retrieved the page, but before you've clicked on a task, you will

see the wrong task in the details page.  Your options are as follows:

1) Keep the current list in session and provide an explicit "Refresh"
button.

2) Use the extended datatable with forceIdIndexFormula

#1 is bad because hitting the refresh button on the browser doesn't
work, and I don't think its too much to expect it to.  You also have to
keep the list around in memory just to support the framework

#2 is bad because of the above mentioned performance issues.  The
functionality, however, does work as expected and would probably be the
preferred way to go

A more general issue with #2, however, is that you'd need special
knowledge to know option #2 even existed, and why it should be used.
That particular bug is of the worst kind because you wouldn't see it
unless you had fairly high system volume.  Then, of course, we're going
to blame it on user error.  "Oh, those ops people, they're so clueless".

 You know?

Rant over.  Sorry for cluttering up mailboxes!

-Kevin

CONNER, BRENDAN (SBCSI) wrote:

Hmm.  Sorry I wasn't much help.

That reminds me, though.  On a related topic, I do know that there's a
glaring bug in O'Reilly.  Specifically, in the code for example 10-1

(p.

176), it lists:

public DataModel getReportsModel() {
     if (reportsModel == null) {
             reportsModel = new ListDataModel();
     }
     reportsModel.setWrappedData(getReports()); // wrong
     return reportsModel;
}

In case anyone in the discussion group is using this example, please
note that the above should be changed to:

public DataModel getReportsModel() {
     if (reportsModel == null) {
             reportsModel = new ListDataModel();
             reportsModel.setWrappedData(getReports()); // this
should be inside the if statement
     }
     return reportsModel;
}

In case anyone else is trying out the O'Reilly example, that bug can
cause no end of frustration.

- Brendan

-----Original Message-----
From: Kevin Galligan [mailto:[EMAIL PROTECTED]
Sent: Monday, August 29, 2005 4:25 PM
To: MyFaces Discussion
Subject: Re: Concerning DataModel usage plus overhead?


There's no stumbling block.  I'm saying that if you're trying to
implement the "classic" model of getting a view of entries from a
database table, or a similar data store, you can easily run into
trouble.  Performance trouble, feature trouble, or actual bug trouble.

My obvious example is the O'Reilly book.  Unaltered, I was able to

make

it do "flakey selections".  Click on a row, but get a different detail

to show up.

"By the way, regardless of whether one is using JSF, the data from
queries become stale the minute one's transaction has ended."

True.  However, if you use the "classic" model, if you click on an

entry

and link-by-id, even though the total list has changed, you'll still

get

the detail for the particular row you've clicked on.  Yes?  Even if

the

detail data has been altered, you still get the correct row.  This is
not true with the pattern I'm talking about (and can publicly be seen

in

the O'Reilly book example).  Its not *that* bad in this example

because

you're just selecting something, but its still bad.

I guess that's my point.  I proposed a "simple pattern" in my post on
java ranch and I still haven't really found a solution in JSF that

makes

a lot of sense to me, or somebody to give me the preferred way to
implement it.  That's my stumbling block.

I'm really looking for somebody to say, "oh yeah, you want to do x" or

"your assumptions are wrong and it doesn't have the performance issue
you're talking about".  Most of the replies I get feel like they're
working around the implementation.  'DataModel links by index, so you
should keep the list in session and only refresh when the user
explicitly asks for it'.  Stuff like that.  Ok, but that's not how I
think it should work, and in the "classic" pattern, it doesn't work

like

that.

To be clear, using the ext dataTable does solve the consistency

problem,

but at the cost of pushing around a lot of data unnecessarily.  At

least

that's how it looks to me.  The tough part is that nobody seems to

agree

with me, and I don't understand why.  If I had to pinpoint a stumbling

block, that would really, really be it.  I feel like I'm missing a

point

here.  Not how to get it to work, but why we'd want to create and

learn

a new framework, and have to then jump through hoops to implement
something that's pretty simple and common.

I'm really just waiting for the post that I read and then say, "Oh,
right, now I got it".

Thanks again.

CONNER, BRENDAN (SBCSI) wrote:


OK, I misunderstood the problem you're talking about.  So, yes, the
state-saving method is immaterial.  The state-saving method can be
material if a user has more than one window open within a session, in

my


experience.

Well, it's definitely true that DataModel is a "local" snapshot of

what


one queried at a point in time.  Yes, it can become stale.

Typically, your table would contain a list of keys, and, once the user
has clicked on one of the entries, you would ask the DataModel for the
appropriate rowIndex that was selected, and then, at that rowIndex,

you


would get the key for that row, go to the database for the detail, and
then return "success", at which point the detail for that key is
displayed, or the detail and the summary are both displayed, or
whatever.

If you want to redisplay a refreshed version of the summary as well as
the detail, you'd query the database for that as well.

I guess I'd have to have more information to see where the stumbling
block is.  Maybe I'm not having any issues with it because I'm using
<t:saveState>.

- Brendan

-----Original Message-----
From: Kevin Galligan [mailto:[EMAIL PROTECTED]
Sent: Monday, August 29, 2005 3:23 PM
To: MyFaces Discussion
Subject: Re: Concerning DataModel usage plus overhead?


Hmm.  I could, but I'd bet it would be no different.  I don't think

that


takes care of the fundamental problem, which is as follows...

*** Get list of entries ***

Date      Name          Id   Index
8/22/05   First Entry   1    0
8/22/05   Second Entry  2    1
8/24/05   Third Entry   3    2
8/25/05   Fourth Entry  4    3

That's what you see on your page (the "Index" column would really be
links to a detail page, not an index number.  However, to the system,
its an index number).  While you're looking at that, somebody else

adds


the following...

Date      Name          Id
8/20/05   Older Entry   5

Lets say you then click on entry number 2, "Second Entry", in your

list.


To the system you clicked on index number '1'.  It will get the list


of entries, and the entry at index '1' will be selected.

Since an entry was added while you were looking at the page, when you
get to the detail page you'll actually see "First Entry".

I don't think saving state on the client has anything to do with this.


Its still select-by-index instead of by id.

This is the first issue I had with the DataModel pattern.  You can

avoid


this by keeping the entries in the session.  However, every time you

go


to the list page you'll see stale data.  You'd need to code an

explicit


function and link to dump and refresh the data (and make sure your

users


are aware that they are looking at stale data).

The extended dataTable takes care of this with *forceIdIndexFormula*,
but then you still have the issue that every time you click on a link,


the system does a full data grab.  Worse yet, it then has to scan
through each to find the particular id (*** I may be wrong about that.


If I am, somebody please tell me.  This is part of the reason why I'm
posting ***).

CONNER, BRENDAN (SBCSI) wrote:



Out of curiosity, are you setting javax.faces.STATE_SAVING_METHOD to
client in your web.xml?  If not, can you try doing that and seeing if
you observe the same behavior?

- Brendan

-----Original Message-----
From: Kevin Galligan [mailto:[EMAIL PROTECTED]
Sent: Monday, August 29, 2005 2:50 PM
To: [email protected]
Subject: Re: Concerning DataModel usage plus overhead?


I tried to send this, and I think it failed.  Anyway...

Rick, "To me the above is just really goofy. Unless, there are

security



constraints to me it makes sense to get the item you want back based

on



some key."

You and I are on the same page.  I'm not sure I'd so far as goofy,

but

I



think for particular domains, the DataModel pattern isn't really the

way



to go.

Brendan "It's just that JSF offers the DataModel abstraction such

that,



when the user clicks on your link, your program just has to ask
DataModel for rowIndex to locate the row that was selected.  *It's
designed to simplify your coding.*"

If you look through the post I pasted in my message, I had a fairly
serious problem with the DataModel.  I was using it to show a list of
entries from a database.  When the user visits the page, it grabs the
list from the database and displays it.  I was able to take the

example

from the O'Reilly book and break it.  How?  Basically...


1) Get the list of entries on one browser screen
2) Open a different browser and add an entry
3) Go back to the original browser and click an entry

If you do it in the "magic" order, you'll wind up selecting a

different



row than you clicked on.  This is because the DataModel uses a

numerical



index instead of a internally meaningful id value.

If you use the extended dataTable and the forceIdIndexFormula, you

can

index by an id value, but its still doing some strange dynamics.  I'm
guessing, but I think when the user clicks, the system would have to

get



the full list again, scan through it, and then select the value you
want.  Its self-consistant in that it'll select the correct entry,

and

maybe its conceptually simpler, but at the expense of significant
processing and data access.

In the post I asked if anybody used more of a hybrid approach.  Do

your



lists with "classic" link-by-id design, grab the singular value, and
pass to a jsf page.  I also had some thoughts on implementing this
directly in JSF, but in a way that avoided double data grabs or
link-by-index designs.

Ok, back to my reguarl day job...

(thanks in advance, again)

CONNER, BRENDAN (SBCSI) wrote:




Yes, you could do your own parameter passing.  It's just that JSF

offers




the DataModel abstraction such that, when the user clicks on your

link,




your program just has to ask DataModel for rowIndex to locate the

row


that was selected.  It's designed to simplify your coding.

In the applications I've worked on, we very rarely have to

explicitly


pass request parameters.  Pretty much everything is in the bean.

- Brendan

-----Original Message-----
*From:* Rick Reumann [mailto:[EMAIL PROTECTED]
*Sent:* Monday, August 29, 2005 2:09 PM
*To:* MyFaces Discussion
*Subject:* Re: Concerning DataModel usage plus overhead?

On 8/29/05, *Kevin Galligan* <[EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]>> wrote:

     If you use the standard dataTable, you have to
    keep your values in session between the time you show the list
    and when
    they click on the value.  If you get the values from the db

each




    time,
    you open the possibility that the index will have changed, and

the




    selected value will be incorrect.  If you keep the values in
    session,
    its keeping a lot of data around, and you need to explicitly
    code a refresh.


To me the above is just really goofy. Unless, there are security
constraints to me it makes sense to get the item you want back

based




on some key. Maybe for example you are looking at a list of care
models on a page, then you want to see the details of the car. It
makes most sense to me to click on the car model passing the id of
the model you want, you look up the model and you pass it back.

When




you need the list of cars back, get a fresh set from the backend.

If




you need caching, cache at the persistence layer.

I don't see the advantage of saving the state of a DataModel, but
I'm new to all of this, so maybe I'll see the light at some point.

--
Rick







Reply via email to