Hi, Paul, Daniel and all list.
I'm really glad finding this discussion, I guess in all serious projects
there is a need for reading large tables. I was reading the Wiki page, and
had a trouble of implementing it, though after reading this thread I've got
it working, at least to some extent.
I'm using Facelets 1.1.11 with MyFaces 1.1.3 -snapshot and tomahawk 1.1.3 (I
was trying later versions, but facelets complained on server start, althoug
I did not see real issues). The DB is MySql 5 and Hibernate is DB wrapper..
I do have some questions (3 total):
1. I've added your method in my bean:
public DataPage<Customer> fetchPage(int startRow, int pageSize) {
log.debug("=== LocalDataModel.fetchPage startRow: "+ startRow+"
pageSize: "+pageSize);
return *doFetchPage(*startRow, pageSize);
}
Still, I can see two DB roundtrips when doing 'next page'
this is what I see in the log:
OPENING PAGE First Time - no problem
Jul 5, 2007 1:12:09 PM com.sun.facelets.tag.jsf.ComponentRule warnAttr
WARNING: /web/sec/examples/largeTableScroller.xhtml @104,85 border="1"
Property 'border' is not on type:
org.apache.myfaces.component.html.ext.HtmlGraphicImage
DEBUG === LocalDataModel.fetchPage startRow: 0 pageSize: 5
DEBUG **Fetch: required -> fetching...
DEBUG === Gettin new page. startRow = 0 size: 5
DEBUG attempting to initialize the SessionFactory
INFO Hibernate 3.2.4.sp1
..... multiple infos from Hibernate about session initialization.........
Hibernate: select this_.Cust_ID as Cust1_0_0_, this_.Name as Name0_0_,
this_.Phone_Number as Phone3_0_0_, this_.Street_A
ddress as Street4_0_0_, this_.City as City0_0_, this_.State as State0_0_
from customers this_ limit ?
DEBUG === LocalDataModel.fetchPage startRow: 0 pageSize: 5
DEBUG ***Fetch: not required (already fetched)!
INFO entering RESTORE_VIEW(1) in org.apache.myfaces.lifecycle.LifecycleImpl
INFO entering RESTORE_VIEW(1) in org.apache.myfaces.lifecycle.LifecycleImpl
SCROLLING TO THE NEXT PAGE - unwanted read
INFO entering RESTORE_VIEW(1) in org.apache.myfaces.lifecycle.LifecycleImpl
INFO entering APPLY_REQUEST_VALUES(2) in
org.apache.myfaces.lifecycle.LifecycleImpl
*DEBUG === LocalDataModel.fetchPage startRow: 0 pageSize: 5 ???????
*DEBUG **Fetch: required -> fetching...
DEBUG === Gettin new page. startRow = 0 size: 5
Hibernate: select this_.Cust_ID as Cust1_0_0_, this_.Name as Name0_0_,
this_.Phone_Number as Phone3_0_0_, this_.Street_A
ddress as Street4_0_0_, this_.City as City0_0_, this_.State as State0_0_
from customers this_ limit ?
DEBUG Page Size: 5
DEBUG === LocalDataModel.fetchPage startRow: 0 pageSize: 5
DEBUG ***Fetch: not required (already fetched)!
*DEBUG === LocalDataModel.fetchPage startRow: 5 pageSize: 5 - this is
what was expected
*DEBUG **Fetch: required -> fetching...
DEBUG === Gettin new page. startRow = 5 size: 5
Hibernate: select this_.Cust_ID as Cust1_0_0_, this_.Name as Name0_0_,
this_.Phone_Number as Phone3_0_0_, this_.Street_A
ddress as Street4_0_0_, this_.City as City0_0_, this_.State as State0_0_
from customers this_ limit ?, ?
DEBUG Page Size: 5
INFO entering RESTORE_VIEW(1) in org.apache.myfaces.lifecycle.LifecycleImpl
INFO entering RESTORE_VIEW(1) in org.apache.myfaces.lifecycle.LifecycleImpl
Well, apparently the framework (can I say it better?) is calling fetchPage()
twice. First - with the old startRow value and second -with the new startRow
value.
2. I also can see a warning:WARNING:
/web/sec/examples/largeTableScroller.xhtml @104,85 border="1" Property
'border' is not on type:
org.apache.myfaces.component.html.ext.HtmlGraphicImage
but it seems that the property gets applied. (I can see the differense in
apearance, when the border=1 is removed).
3. I also have a question about dataSize in your DataPage. Does it mean that
the for a first time I have to run something like "select count(*)..." and
then store this value to the session, so it may be retrieved for all
consecutive reads? Do you have a better solution?
On 7/5/07, Paul Iov <[EMAIL PROTECTED]> wrote:
Hi Daniel,
unfortunately I have neither some simple project nor article explaining
this. I have implemented it in my own meta framework which is part of a
big commercial application. (It consists currently of 6 or 7 different
Eclipse projects, so it would be really difficult to extract 'clearly'
the code, you are asking for.) I'm attaching just three classes from my
early 'playground' code. Sorry, it's the best I can offer right now :(
You will not be able to compile this (because the rest of my stuff have
nothing to do with fetching itself and would be more complicated as
helpful) but you can track the approach. There are three methods, which
shows how it works and how to get ride of duplicated (exactly: multiple)
fetching of the same data: getPage() and doFetchPage() in
DataPagedListDataModel<T> and getDataModel() in PagedListFoto (which
extends the DataPagedListDataModel indirectly)
The solution is to separate the fetching call into own method in base
abstract class. (Why it should be abstract is explained in Wiki.)
private int _lastStartRow = -1;
private int _lastPageSize = -1;
private DataPage<T> _lastPage = null;
private DataPage<T> doFetchPage(int startRow, int pageSize){
if ((_lastPage == null) || (_lastStartRow != startRow) ||
(_lastPageSize != pageSize)){
_log.debug("**Fetch: required -> fetching...");
_lastPage = fetchPage(startRow, pageSize);
//store values to chech next time
_lastStartRow = startRow;
_lastPageSize = pageSize;
}else{
_log.debug("***Fetch: not required (already fetched)!");
}
return _lastPage;
}
I store then the startRow and pageSize values and check it every time
the new fetch is 'requested'. Just take a look at my debug statements
entire the code, they should be self explained. The fetching take place
exactly one time for particularly page of data.
One more thing to be clearly explained here: the getDataModel() of
'enclosing' nested class (PagedListFoto in my case) MUST BE CALLED
TWICE, since you have two components in your JSP -> the DataTable and
the Scroller and both are accessing this property. So you have to handle
this situation yourself, i.e. directly in getter:
public DataModel getDataModel() {
_log.debug("-------------- getDataModel() called -------");
if (dataModel == null) {
dataModel = new LocalDataModel(rowsPerPage);
}
return dataModel;
}
I hope it helps.
Regards,
paul
P.S. As mentioned, I'm not using t:dataScroller since it's buggy in
combination with AJAX (at least: it WAS buggu in 1.1.4 and 1.1.5), but I
think, it makes no difference regarding fetching approach itself. I've
send my code with few minor improvements to Adrian Mitev (author of
original component, which was published at
https://ajax4jsf.dev.java.net/servlets/ProjectDocumentList?folderID=6510&expandFolder=6510&folderID=5320
).
If you are interested in this component, just ask him about it.
daniel ccss schrieb:
>
> Thanks!!!
>
> Paul do you have a simple project where I can see how all working
> together, I'm really tire of search and search for solutions and
> nothing , I´m new in this and really need help, thanks!!
>
>
> P.D: have you publish some article explaining how all this works (your
> DataScroller using AjaxDataScroller and the approach of the wiki)?...
> you should i know that many people will appreciate it!
>