You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Yee CN <ye...@streamyx.com> on 2006/01/14 06:25:29 UTC

JSF Flaw: Comopnent not preserving it state

I definitely consider this a flaw. There is no reason why a dataTable should
behave differently from an inputText. preserveDataModel should be enforced
in all components and enabled by default. It should only be disabled with
explicit settings.

This has been a major stumbling block for me to get a clear understanding of
the JSF technology. Judging from the discussions in this news group - I
think I am not the only one.

What is the possibility of rectifying this in JSF spec?

Regards,
Yee

-----Original Message-----
From: Simon Kitching [mailto:skitching@apache.org] 
Sent: Saturday, 14 January 2006 12:15 PM
To: MyFaces Discussion
Subject: Re: AW: An optimised pattern for using t:dataTable - please verify.

On Fri, 2006-01-13 at 15:27 +0100, Matthias Kahlau wrote:
> Hi Simon!
> 
> You wrote:
> 
> > NB: The default behaviour (no preserveDataModel) is flawed because it
> > doesn't get (2) right for datasets that may be changed by something
> > other than the viewing user.
> 
> Isn't this only a problem if the dataModel is directly backed by the
> database, so that the database is accessed on each call of getDataModel()?

Well, it's flawed for any "dataset that may be changed by something
other than the viewing user". But yes the most common situation that
occurs in is when an app is retrieving data from a shared database.

When all the data is held in memory and does not change (ie is static
"reference" data) then of course the default behaviour is fine. However
that isn't often the case.

Regards,

Simon


RE: JSF Flaw: Comopnent not preserving it state

Posted by Yee CN <ye...@streamyx.com>.
The dataTable in ASP.NET is a container - it is a collection of rows, which
is a collection of columns that can hold textboxes, checkboxes etc that
holds the data being displayed in the browser. In ASP.NET the view
components are standalone passive data holders. They are not connected to
any data object as JSF components do with value bindings. 

The modus operandi is that the program code will give them the data, and
from there they will just dutifully maintain the data until they get changed
by the user or the program code give them something else.

Another big distinction between ASP.NET and JSF is that every Web Form (the
.aspx page) is associated with a code behind form (basically a class file).
The Web Form and the code behind are compiled together as a single class.
The IDE plays a central role in aspx development. It has to make sure that
components added at the aspx script got a corresponding object definition in
the code behind.

JSF is component centric, while ASP.NET is code centric. I don't see one as
superior to another, but I do think that JSF spec is too loose at present,
and can easily subject itself to anti-patterns. I think framework like Shale
is necessary to make JSF successful.


Regards,
Yee

-----Original Message-----
From: Simon Kitching [mailto:skitching@apache.org] 
Sent: Sunday, 15 January 2006 12:20 PM
To: 'MyFaces Discussion'
Subject: RE: JSF Flaw: Comopnent not preserving it state

On Sun, 2006-01-15 at 01:18 +0800, Yee CN wrote:
> Simon,
> 
> It is a lot more complex than it looks on the surface. Looks like I have
> opened a can of worms.

Yep :-)

> 
> Firstly Hibernate LazyInitializationException problem is inherent in the
> SessionPerRequest pattern. It is universal to all web based framework, so
it
> is not unique to JSF. There are attempts to circumvent this - the SEAM
> framework is an example; it is based on JSF/EJB3. It is a well known
problem
> that everybody learned to deal with it after a while.

Agreed. All that Rich was pointing out is that in some cases,
serialize/deserialize (what you were recommending) behaves differently
from refetch (the current default). So users will need to know about
both possible solutions and choose between them depending on their
circumstances.

> 
> Secondly the 'correct' behavior should not depend on any particular use
> case. It is simply that Restore-View should do what it says - to restore
in
> the server the view that was being rendered to the browser. That would
> include the component tree as well as the data being displayed.

I think that h:dataTable is different from components like h:inputText.
The difference is that the former's associated data is *user model*
objects, while the latter component's data is simply a *java standard
datatype*.

The select components (eg h:selectOneMenu) probably have the same issues
as h:dataTable if the option to bind the value to a Map object is used.
And currently I bet both the RI and MyFaces use the same approach as
currently used by h:dataTable, ie that after submit the component
refetches the data from the user model. I haven't checked that, though,
so correction welcome.

> 
> At this stage I still feel that what I proposed in my last posting is the
> right approach. There is no ambiguity semantically. Yes the dataModel will
> have to be serializable, but I do not see any solution to this problem
> otherwise.
> 
> As a point of reference, this is how ASP.NET works - its dataTable is
> basically a grid, you would do whatever to populate the grid, and from
there
> you will be working with rows and columns. There is not dataModel as such.
> It is a simpler framework, but does not suffer the problems we are facing
> here.

I would be interested in learning more about how ASP.NET deals with
this. What exactly happens when a dataTable is associated with user
objects?

> 
> >The only thing that is quite clear is that someone should patch
> >t:dataTable (and maybe h:dataTable) so that on processDecodes it walks
> >its children and checks if any implements EditableValueHolder. If not,
> >it should skip fetching of the dataModel. I can't see any justification
> >for fetching again when the table has no input components. 
> 
> I think this is not going to work - as the datatables are generally not
> editable, but yet we still need to know which row is being clicked on and
> the corresponding record data. 

Good point. Any command component in the table also needs to have its
decode called, and the table associated with the correct DataModel
component at that time. This is a lot more common than input components
in a table, so my suggested optimisation (while still valid I think)
won't help in as many situations as I'd hoped.

> 
> I think this problem should be addressed at the JSF spec level - not at
the
> level of any particular implementation. At present t:dataTable is workable
> with the patterns that I proposed. But h:dataTable is definitely
> problematic.

I think the preserveDataModel functionality can be emulated by simply
using a t:saveState component to save the data model explicitly. This
means that your pattern can be applied to h:dataTable too.

public class MyBackingBean {
  private DataModel dataModel;

  public DataModel getDataModel() {
    if (this.dataModel != null)
      return this.dataModel;
    // create and populate the dataModel
  
  }

  public void setDataModel(DataModel model) {
    this.dataModel = model;
  }
}


in page:
  <t:saveState id="dataModel" value="#{backingBean.dataModel}"/>
  <h:dataModel value="#{backingBean.dataModel}" ....>

I haven't tested this, but don't see why it wouldn't work.

Regards,

Simon


RE: JSF Flaw: Comopnent not preserving it state

Posted by Simon Kitching <sk...@apache.org>.
On Sun, 2006-01-15 at 01:18 +0800, Yee CN wrote:
> Simon,
> 
> It is a lot more complex than it looks on the surface. Looks like I have
> opened a can of worms.

Yep :-)

> 
> Firstly Hibernate LazyInitializationException problem is inherent in the
> SessionPerRequest pattern. It is universal to all web based framework, so it
> is not unique to JSF. There are attempts to circumvent this - the SEAM
> framework is an example; it is based on JSF/EJB3. It is a well known problem
> that everybody learned to deal with it after a while.

Agreed. All that Rich was pointing out is that in some cases,
serialize/deserialize (what you were recommending) behaves differently
from refetch (the current default). So users will need to know about
both possible solutions and choose between them depending on their
circumstances.

> 
> Secondly the 'correct' behavior should not depend on any particular use
> case. It is simply that Restore-View should do what it says - to restore in
> the server the view that was being rendered to the browser. That would
> include the component tree as well as the data being displayed.

I think that h:dataTable is different from components like h:inputText.
The difference is that the former's associated data is *user model*
objects, while the latter component's data is simply a *java standard
datatype*.

The select components (eg h:selectOneMenu) probably have the same issues
as h:dataTable if the option to bind the value to a Map object is used.
And currently I bet both the RI and MyFaces use the same approach as
currently used by h:dataTable, ie that after submit the component
refetches the data from the user model. I haven't checked that, though,
so correction welcome.

> 
> At this stage I still feel that what I proposed in my last posting is the
> right approach. There is no ambiguity semantically. Yes the dataModel will
> have to be serializable, but I do not see any solution to this problem
> otherwise.
> 
> As a point of reference, this is how ASP.NET works - its dataTable is
> basically a grid, you would do whatever to populate the grid, and from there
> you will be working with rows and columns. There is not dataModel as such.
> It is a simpler framework, but does not suffer the problems we are facing
> here.

I would be interested in learning more about how ASP.NET deals with
this. What exactly happens when a dataTable is associated with user
objects?

> 
> >The only thing that is quite clear is that someone should patch
> >t:dataTable (and maybe h:dataTable) so that on processDecodes it walks
> >its children and checks if any implements EditableValueHolder. If not,
> >it should skip fetching of the dataModel. I can't see any justification
> >for fetching again when the table has no input components. 
> 
> I think this is not going to work - as the datatables are generally not
> editable, but yet we still need to know which row is being clicked on and
> the corresponding record data. 

Good point. Any command component in the table also needs to have its
decode called, and the table associated with the correct DataModel
component at that time. This is a lot more common than input components
in a table, so my suggested optimisation (while still valid I think)
won't help in as many situations as I'd hoped.

> 
> I think this problem should be addressed at the JSF spec level - not at the
> level of any particular implementation. At present t:dataTable is workable
> with the patterns that I proposed. But h:dataTable is definitely
> problematic.

I think the preserveDataModel functionality can be emulated by simply
using a t:saveState component to save the data model explicitly. This
means that your pattern can be applied to h:dataTable too.

public class MyBackingBean {
  private DataModel dataModel;

  public DataModel getDataModel() {
    if (this.dataModel != null)
      return this.dataModel;
    // create and populate the dataModel
  
  }

  public void setDataModel(DataModel model) {
    this.dataModel = model;
  }
}


in page:
  <t:saveState id="dataModel" value="#{backingBean.dataModel}"/>
  <h:dataModel value="#{backingBean.dataModel}" ....>

I haven't tested this, but don't see why it wouldn't work.

Regards,

Simon


RE: JSF Flaw: Comopnent not preserving it state

Posted by Yee CN <ye...@streamyx.com>.
Simon,

It is a lot more complex than it looks on the surface. Looks like I have
opened a can of worms.

Firstly Hibernate LazyInitializationException problem is inherent in the
SessionPerRequest pattern. It is universal to all web based framework, so it
is not unique to JSF. There are attempts to circumvent this - the SEAM
framework is an example; it is based on JSF/EJB3. It is a well known problem
that everybody learned to deal with it after a while.

Secondly the 'correct' behavior should not depend on any particular use
case. It is simply that Restore-View should do what it says - to restore in
the server the view that was being rendered to the browser. That would
include the component tree as well as the data being displayed.

At this stage I still feel that what I proposed in my last posting is the
right approach. There is no ambiguity semantically. Yes the dataModel will
have to be serializable, but I do not see any solution to this problem
otherwise.

As a point of reference, this is how ASP.NET works - its dataTable is
basically a grid, you would do whatever to populate the grid, and from there
you will be working with rows and columns. There is not dataModel as such.
It is a simpler framework, but does not suffer the problems we are facing
here.

>The only thing that is quite clear is that someone should patch
>t:dataTable (and maybe h:dataTable) so that on processDecodes it walks
>its children and checks if any implements EditableValueHolder. If not,
>it should skip fetching of the dataModel. I can't see any justification
>for fetching again when the table has no input components. 

I think this is not going to work - as the datatables are generally not
editable, but yet we still need to know which row is being clicked on and
the corresponding record data. 

I think this problem should be addressed at the JSF spec level - not at the
level of any particular implementation. At present t:dataTable is workable
with the patterns that I proposed. But h:dataTable is definitely
problematic.

Regards,
Yee


-----Original Message-----
From: Simon Kitching [mailto:skitching@apache.org] 
Sent: Saturday, 14 January 2006 6:48 PM
To: 'MyFaces Discussion'
Subject: RE: JSF Flaw: Comopnent not preserving it state

Rich's point is a good one. If you load an entity from a database using
Hibernate, it is a "live" object in that you can follow its references
to other objects and they will transparently get loaded from the
database too (lazy relations). However if you serialize the object then
deserialize it the object becomes "detached", and following any lazy
relation results in a LazyInitializationException. In this case,
refetching during the validate phase can in fact be quite different from
deserializing.




Also, objects in the list may not be serializable so defaulting to
preserveDataModel just isn't an option in that case.

I think your proposal is a good one in many cases, but I also think that
the "correct" solution for a particular data table depends on a number
of factors. I've started to list them, and what they imply for the
"correct" usage of a datatable - and it's got very complex!

The only thing that is quite clear is that someone should patch
t:dataTable (and maybe h:dataTable) so that on processDecodes it walks
its children and checks if any implements EditableValueHolder. If not,
it should skip fetching of the dataModel. I can't see any justification
for fetching again when the table has no input components.

I've got this on my to-do list, but unfortunately there are quite a few
things in front of it!

Cheers,

Simon


On Sat, 2006-01-14 at 15:20 +0800, Yee CN wrote: 
> Rich,
> 
> Actually my proposal is specifically to prevent the issues you described.
> Please refer to the thread "An optimised pattern for using t:dataTable -
> please verify". This is where the current thread originates from.
> 
> Regards,
> Yee
> 
> -----Original Message-----
> From: Richard Wallace [mailto:rwallace@thewallacepack.net] 
> Sent: Saturday, 14 January 2006 3:04 PM
> To: MyFaces Discussion
> Subject: Re: JSF Flaw: Comopnent not preserving it state
> 
> The biggest problem I can see with making the default value for this 
> true for the dataTable component is that the DataModel could very well 
> be backed by data loaded from an ORM tool such as Hibernate.  In this 
> case, it would be very easy to run into LazyInitializationExceptions or 
> equivalent.  Also, as pointed out, if the data is loaded from the 
> database, other users interacting with the system could cause a user to 
> see stale data.  A refresh button for the table is a poor solution to 
> this, because in my experience when a user sees a new page load they 
> expect the data to be the latest.  Making them have to hit an additional 
> refresh button would just confuse them.
> 
> On a bit of a different note, something I've run into with DataTables 
> that bugs me is the way JSF handles the Master-Detail pattern.  Using 
> the traditional way of finding the object the user selected with the 
> DataModel.getRowData() method is error-prone if another user adds an 
> object that would appear in the table before the one the user is trying 
> to drill-down on.  The user could wind up with an off-by-one error, 
> getting the object above the one they selected.  I don't know what the 
> best solution to this is.  In the past I've tried to use the 
> t:updateActionListener to set an id parameter in the backing bean and 
> load just the object I'm interested in for the details as an alternative 
> to using the DataModel.getRowData() method.  But I'm not sure that's any 
> better for consistency because I'm not sure when the parameter for the 
> updateActionListener is actually set.  If it's when the master page is 
> loaded, then it will work fine.  But if it's when the view is being 
> restored when the link to go to the detail page is clicked, then this is 
> still error-prone.  Of course, it also doesn't solve the problem of 
> having to do the select for all the things that would show up in the 
> master list when all you're interested in is the single object you want 
> to get details on.
> 
> Just my 2c worth.
> 
> Rich
> 
> Yee CN wrote:
> > I definitely consider this a flaw. There is no reason why a dataTable
> should
> > behave differently from an inputText. preserveDataModel should be
enforced
> > in all components and enabled by default. It should only be disabled
with
> > explicit settings.
> >
> > This has been a major stumbling block for me to get a clear
understanding
> of
> > the JSF technology. Judging from the discussions in this news group - I
> > think I am not the only one.
> >
> > What is the possibility of rectifying this in JSF spec?
> >
> > Regards,
> > Yee
> >
> > -----Original Message-----
> > From: Simon Kitching [mailto:skitching@apache.org] 
> > Sent: Saturday, 14 January 2006 12:15 PM
> > To: MyFaces Discussion
> > Subject: Re: AW: An optimised pattern for using t:dataTable - please
> verify.
> >
> > On Fri, 2006-01-13 at 15:27 +0100, Matthias Kahlau wrote:
> >   
> >> Hi Simon!
> >>
> >> You wrote:
> >>
> >>     
> >>> NB: The default behaviour (no preserveDataModel) is flawed because it
> >>> doesn't get (2) right for datasets that may be changed by something
> >>> other than the viewing user.
> >>>       
> >> Isn't this only a problem if the dataModel is directly backed by the
> >> database, so that the database is accessed on each call of
> getDataModel()?
> >>     
> >
> > Well, it's flawed for any "dataset that may be changed by something
> > other than the viewing user". But yes the most common situation that
> > occurs in is when an app is retrieving data from a shared database.
> >
> > When all the data is held in memory and does not change (ie is static
> > "reference" data) then of course the default behaviour is fine. However
> > that isn't often the case.
> >
> > Regards,
> >
> > Simon
> >
> >   
> 


RE: JSF Flaw: Comopnent not preserving it state

Posted by Simon Kitching <sk...@apache.org>.
Rich's point is a good one. If you load an entity from a database using
Hibernate, it is a "live" object in that you can follow its references
to other objects and they will transparently get loaded from the
database too (lazy relations). However if you serialize the object then
deserialize it the object becomes "detached", and following any lazy
relation results in a LazyInitializationException. In this case,
refetching during the validate phase can in fact be quite different from
deserializing.

Also, objects in the list may not be serializable so defaulting to
preserveDataModel just isn't an option in that case.

I think your proposal is a good one in many cases, but I also think that
the "correct" solution for a particular data table depends on a number
of factors. I've started to list them, and what they imply for the
"correct" usage of a datatable - and it's got very complex!

The only thing that is quite clear is that someone should patch
t:dataTable (and maybe h:dataTable) so that on processDecodes it walks
its children and checks if any implements EditableValueHolder. If not,
it should skip fetching of the dataModel. I can't see any justification
for fetching again when the table has no input components.

I've got this on my to-do list, but unfortunately there are quite a few
things in front of it!

Cheers,

Simon


On Sat, 2006-01-14 at 15:20 +0800, Yee CN wrote: 
> Rich,
> 
> Actually my proposal is specifically to prevent the issues you described.
> Please refer to the thread "An optimised pattern for using t:dataTable -
> please verify". This is where the current thread originates from.
> 
> Regards,
> Yee
> 
> -----Original Message-----
> From: Richard Wallace [mailto:rwallace@thewallacepack.net] 
> Sent: Saturday, 14 January 2006 3:04 PM
> To: MyFaces Discussion
> Subject: Re: JSF Flaw: Comopnent not preserving it state
> 
> The biggest problem I can see with making the default value for this 
> true for the dataTable component is that the DataModel could very well 
> be backed by data loaded from an ORM tool such as Hibernate.  In this 
> case, it would be very easy to run into LazyInitializationExceptions or 
> equivalent.  Also, as pointed out, if the data is loaded from the 
> database, other users interacting with the system could cause a user to 
> see stale data.  A refresh button for the table is a poor solution to 
> this, because in my experience when a user sees a new page load they 
> expect the data to be the latest.  Making them have to hit an additional 
> refresh button would just confuse them.
> 
> On a bit of a different note, something I've run into with DataTables 
> that bugs me is the way JSF handles the Master-Detail pattern.  Using 
> the traditional way of finding the object the user selected with the 
> DataModel.getRowData() method is error-prone if another user adds an 
> object that would appear in the table before the one the user is trying 
> to drill-down on.  The user could wind up with an off-by-one error, 
> getting the object above the one they selected.  I don't know what the 
> best solution to this is.  In the past I've tried to use the 
> t:updateActionListener to set an id parameter in the backing bean and 
> load just the object I'm interested in for the details as an alternative 
> to using the DataModel.getRowData() method.  But I'm not sure that's any 
> better for consistency because I'm not sure when the parameter for the 
> updateActionListener is actually set.  If it's when the master page is 
> loaded, then it will work fine.  But if it's when the view is being 
> restored when the link to go to the detail page is clicked, then this is 
> still error-prone.  Of course, it also doesn't solve the problem of 
> having to do the select for all the things that would show up in the 
> master list when all you're interested in is the single object you want 
> to get details on.
> 
> Just my 2c worth.
> 
> Rich
> 
> Yee CN wrote:
> > I definitely consider this a flaw. There is no reason why a dataTable
> should
> > behave differently from an inputText. preserveDataModel should be enforced
> > in all components and enabled by default. It should only be disabled with
> > explicit settings.
> >
> > This has been a major stumbling block for me to get a clear understanding
> of
> > the JSF technology. Judging from the discussions in this news group - I
> > think I am not the only one.
> >
> > What is the possibility of rectifying this in JSF spec?
> >
> > Regards,
> > Yee
> >
> > -----Original Message-----
> > From: Simon Kitching [mailto:skitching@apache.org] 
> > Sent: Saturday, 14 January 2006 12:15 PM
> > To: MyFaces Discussion
> > Subject: Re: AW: An optimised pattern for using t:dataTable - please
> verify.
> >
> > On Fri, 2006-01-13 at 15:27 +0100, Matthias Kahlau wrote:
> >   
> >> Hi Simon!
> >>
> >> You wrote:
> >>
> >>     
> >>> NB: The default behaviour (no preserveDataModel) is flawed because it
> >>> doesn't get (2) right for datasets that may be changed by something
> >>> other than the viewing user.
> >>>       
> >> Isn't this only a problem if the dataModel is directly backed by the
> >> database, so that the database is accessed on each call of
> getDataModel()?
> >>     
> >
> > Well, it's flawed for any "dataset that may be changed by something
> > other than the viewing user". But yes the most common situation that
> > occurs in is when an app is retrieving data from a shared database.
> >
> > When all the data is held in memory and does not change (ie is static
> > "reference" data) then of course the default behaviour is fine. However
> > that isn't often the case.
> >
> > Regards,
> >
> > Simon
> >
> >   
> 


RE: JSF Flaw: Comopnent not preserving it state

Posted by Yee CN <ye...@streamyx.com>.
Rich,

Actually my proposal is specifically to prevent the issues you described.
Please refer to the thread "An optimised pattern for using t:dataTable -
please verify". This is where the current thread originates from.

Regards,
Yee

-----Original Message-----
From: Richard Wallace [mailto:rwallace@thewallacepack.net] 
Sent: Saturday, 14 January 2006 3:04 PM
To: MyFaces Discussion
Subject: Re: JSF Flaw: Comopnent not preserving it state

The biggest problem I can see with making the default value for this 
true for the dataTable component is that the DataModel could very well 
be backed by data loaded from an ORM tool such as Hibernate.  In this 
case, it would be very easy to run into LazyInitializationExceptions or 
equivalent.  Also, as pointed out, if the data is loaded from the 
database, other users interacting with the system could cause a user to 
see stale data.  A refresh button for the table is a poor solution to 
this, because in my experience when a user sees a new page load they 
expect the data to be the latest.  Making them have to hit an additional 
refresh button would just confuse them.

On a bit of a different note, something I've run into with DataTables 
that bugs me is the way JSF handles the Master-Detail pattern.  Using 
the traditional way of finding the object the user selected with the 
DataModel.getRowData() method is error-prone if another user adds an 
object that would appear in the table before the one the user is trying 
to drill-down on.  The user could wind up with an off-by-one error, 
getting the object above the one they selected.  I don't know what the 
best solution to this is.  In the past I've tried to use the 
t:updateActionListener to set an id parameter in the backing bean and 
load just the object I'm interested in for the details as an alternative 
to using the DataModel.getRowData() method.  But I'm not sure that's any 
better for consistency because I'm not sure when the parameter for the 
updateActionListener is actually set.  If it's when the master page is 
loaded, then it will work fine.  But if it's when the view is being 
restored when the link to go to the detail page is clicked, then this is 
still error-prone.  Of course, it also doesn't solve the problem of 
having to do the select for all the things that would show up in the 
master list when all you're interested in is the single object you want 
to get details on.

Just my 2c worth.

Rich

Yee CN wrote:
> I definitely consider this a flaw. There is no reason why a dataTable
should
> behave differently from an inputText. preserveDataModel should be enforced
> in all components and enabled by default. It should only be disabled with
> explicit settings.
>
> This has been a major stumbling block for me to get a clear understanding
of
> the JSF technology. Judging from the discussions in this news group - I
> think I am not the only one.
>
> What is the possibility of rectifying this in JSF spec?
>
> Regards,
> Yee
>
> -----Original Message-----
> From: Simon Kitching [mailto:skitching@apache.org] 
> Sent: Saturday, 14 January 2006 12:15 PM
> To: MyFaces Discussion
> Subject: Re: AW: An optimised pattern for using t:dataTable - please
verify.
>
> On Fri, 2006-01-13 at 15:27 +0100, Matthias Kahlau wrote:
>   
>> Hi Simon!
>>
>> You wrote:
>>
>>     
>>> NB: The default behaviour (no preserveDataModel) is flawed because it
>>> doesn't get (2) right for datasets that may be changed by something
>>> other than the viewing user.
>>>       
>> Isn't this only a problem if the dataModel is directly backed by the
>> database, so that the database is accessed on each call of
getDataModel()?
>>     
>
> Well, it's flawed for any "dataset that may be changed by something
> other than the viewing user". But yes the most common situation that
> occurs in is when an app is retrieving data from a shared database.
>
> When all the data is held in memory and does not change (ie is static
> "reference" data) then of course the default behaviour is fine. However
> that isn't often the case.
>
> Regards,
>
> Simon
>
>   


Re: JSF Flaw: Comopnent not preserving it state

Posted by Richard Wallace <rw...@thewallacepack.net>.
The biggest problem I can see with making the default value for this 
true for the dataTable component is that the DataModel could very well 
be backed by data loaded from an ORM tool such as Hibernate.  In this 
case, it would be very easy to run into LazyInitializationExceptions or 
equivalent.  Also, as pointed out, if the data is loaded from the 
database, other users interacting with the system could cause a user to 
see stale data.  A refresh button for the table is a poor solution to 
this, because in my experience when a user sees a new page load they 
expect the data to be the latest.  Making them have to hit an additional 
refresh button would just confuse them.

On a bit of a different note, something I've run into with DataTables 
that bugs me is the way JSF handles the Master-Detail pattern.  Using 
the traditional way of finding the object the user selected with the 
DataModel.getRowData() method is error-prone if another user adds an 
object that would appear in the table before the one the user is trying 
to drill-down on.  The user could wind up with an off-by-one error, 
getting the object above the one they selected.  I don't know what the 
best solution to this is.  In the past I've tried to use the 
t:updateActionListener to set an id parameter in the backing bean and 
load just the object I'm interested in for the details as an alternative 
to using the DataModel.getRowData() method.  But I'm not sure that's any 
better for consistency because I'm not sure when the parameter for the 
updateActionListener is actually set.  If it's when the master page is 
loaded, then it will work fine.  But if it's when the view is being 
restored when the link to go to the detail page is clicked, then this is 
still error-prone.  Of course, it also doesn't solve the problem of 
having to do the select for all the things that would show up in the 
master list when all you're interested in is the single object you want 
to get details on.

Just my 2c worth.

Rich

Yee CN wrote:
> I definitely consider this a flaw. There is no reason why a dataTable should
> behave differently from an inputText. preserveDataModel should be enforced
> in all components and enabled by default. It should only be disabled with
> explicit settings.
>
> This has been a major stumbling block for me to get a clear understanding of
> the JSF technology. Judging from the discussions in this news group - I
> think I am not the only one.
>
> What is the possibility of rectifying this in JSF spec?
>
> Regards,
> Yee
>
> -----Original Message-----
> From: Simon Kitching [mailto:skitching@apache.org] 
> Sent: Saturday, 14 January 2006 12:15 PM
> To: MyFaces Discussion
> Subject: Re: AW: An optimised pattern for using t:dataTable - please verify.
>
> On Fri, 2006-01-13 at 15:27 +0100, Matthias Kahlau wrote:
>   
>> Hi Simon!
>>
>> You wrote:
>>
>>     
>>> NB: The default behaviour (no preserveDataModel) is flawed because it
>>> doesn't get (2) right for datasets that may be changed by something
>>> other than the viewing user.
>>>       
>> Isn't this only a problem if the dataModel is directly backed by the
>> database, so that the database is accessed on each call of getDataModel()?
>>     
>
> Well, it's flawed for any "dataset that may be changed by something
> other than the viewing user". But yes the most common situation that
> occurs in is when an app is retrieving data from a shared database.
>
> When all the data is held in memory and does not change (ie is static
> "reference" data) then of course the default behaviour is fine. However
> that isn't often the case.
>
> Regards,
>
> Simon
>
>