You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Costa Basil <co...@yahoo.ca> on 2006/01/04 19:45:46 UTC

Newbie questions - database calls and caching data

Hi

Where is the best place to make database calls to display lists or search results and how to cache them? How can I avoid making unecessary calls to the database?

Here are a two scenarios:

1. Let's say I have a form where the user has to enter data and has to select data from a list or a combobox. The data in these lists come from various database small tables. What is the best place to make the database calls to extract the data for these lists? I looked at the cd catalog sample that comes with the blue print catalog samples, and the database calls are placed in the getXXX methods of the backing beans. Example:

public class AlbumView 
  ...

    public List getTrackList() 
        throws NamingException, SQLException
    {
        int currentId = getCurrentAlbum().getId();
        if(cachedAlbumId != currentId) {
            // If the album id was updated since our last query, query again
            this.trackList = null;
            this.trackCount = -1;
        }
        if(this.trackList == null) {
            Connection connection = getConnection();
            try {
                // Only query if we don't have the result cached for this request.
                PreparedStatement s = getConnection().prepareStatement( 
                    "SELECT track, title FROM songs WHERE album_id = ?");
                s.setInt(1, currentId);
                ResultSet results = s.executeQuery();
                this.trackList = new ArrayList();
                while(results.next()) {
                    TrackData track = new TrackData();
                    track.setTrack(results.getInt("track"));
                    track.setTitle(results.getString("title"));
                    this.trackList.add(track);
                }
                this.cachedAlbumId = currentId;
                results.close();
                s.close();
            } 
            finally {
                connection.close();
            }
        }
        return this.trackList;
    }

and in the jsp page we have:

        <h:dataTable id="dataTable" border="1" value="#{AlbumView.trackList}" 
                     var="track" rendered="#{AlbumView.trackCount > 0}">
          <h:column>

        ...

The AlbumView is a backing bean:
        
  <managed-bean>
    <description>
      The backing bean for the album page
    </description>
    <managed-bean-name>AlbumView</managed-bean-name>
    <managed-bean-class>
      com.sun.j2ee.blueprints.cdcatalog.AlbumView
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>
  
          
What is not clear to me is the following. Let's say the user enters some invalid input and tries to save the data. Because there is some invalid input, then getTrackList will be called again next time the page is displayed. Right? What can I do in order in order to avoid that? I know the data in the track list doesn't change so when the page is re-displayed I don't want to requery the track list from the database.

Another problem that I see with this code is poor error handling. If the app bombs inside getTrackList probably the web application will jump to the jsp error page. Sometimes this is not desirable
Overall, what is your opinion on getting the database data in these getXXX functions? Please ignore the fact that the jdbc calls are placed in the backing bean. 


2. Scenario 2

Searching stuff. Let's say I have a table with employees and I want to find employees by name. Assuming that the whole table with employees is not that big I want to cache the result of the search in memory. 
In case the user opens a new search window, is there an easy way to avoid the clash of two search operations. Scenario: user enters criteria 1, clicks the search button, the app displays the search result, the user opens anther browser window, enters criteria 2, clicks search, the app displays the search result of criteria 2, the user moves to the first window, clicks next page, the app should display the second page of the first search.


Any links to articles or sample applications on these topics are more than welcomed.

Thank you,



		
---------------------------------
Find your next car at Yahoo! Canada Autos

RE: Newbie questions - database calls and caching data

Posted by Tom Butler <to...@adelphia.net>.
Civici - thanks for the information, this is helpful.

 

I have questions about the methods to read the DB:

trackList = getDBHelper().readTrackListFromDB();

 

-       are these methods in your request-scope backing bean?  or are they
methods in another object - if so, is it a managed-request-scope bean?  

 

thanks.

 

  _____  

From: Cagatay Civici [mailto:cagatay.civici@gmail.com] 
Sent: Sunday, January 08, 2006 5:40 AM
To: MyFaces Discussion; skitching@apache.org
Subject: Re: Newbie questions - database calls and caching data

 

Hi,

The practice I am using for a long time to minimize the db access is storing
the data from db in a member variable, this was the one Simon already
suggested. Getters that are bind to the components are called a couple of
times, if you are not careful enough than performance issues will likely to
occur. You should cache the db data in request scope like this; 

public class AlbumView  {
  ...
private List _trackList;
  ...

    public List getTrackList() 
    {
         if(_trackList == null)
                trackList = getDBHelper().readTrackListFromDB(); 
         return trackList;

    }

}

The first access to the list will read the data from db, later accesses will
not hit the db and return the data that is cached. As a good practice maybe
you might have a dbhelper class that reads the tracklist and does other db
related stuff, this will enable you to use the same mechanism easily in
other pages without recoding the sql stuff. 


Re: Newbie questions - database calls and caching data

Posted by Cagatay Civici <ca...@gmail.com>.
Hi,

The practice I am using for a long time to minimize the db access is storing
the data from db in a member variable, this was the one Simon already
suggested. Getters that are bind to the components are called a couple of
times, if you are not careful enough than performance issues will likely to
occur. You should cache the db data in request scope like this;

public class AlbumView  {
  ...
private List _trackList;
  ...

    public List getTrackList()
    {
         if(_trackList == null)
                trackList = getDBHelper().readTrackListFromDB();
         return trackList;
    }

}

The first access to the list will read the data from db, later accesses will
not hit the db and return the data that is cached. As a good practice maybe
you might have a dbhelper class that reads the tracklist and does other db
related stuff, this will enable you to use the same mechanism easily in
other pages without recoding the sql stuff.

RE: Newbie questions - database calls and caching data

Posted by Yee CN <ye...@streamyx.com>.
Please check out the following Wiki by Simon
http://wiki.apache.org/myfaces/WorkingWithLargeTables. It is a framework
that allows you to retrieve your search results one page at a time, so
memory is never a problem - session scope or not.

Regards,
Yee

-----Original Message-----
From: Tom Butler [mailto:tom.butler@adelphia.net] 
Sent: Monday, 9 January 2006 7:14 AM
To: 'MyFaces Discussion'; skitching@apache.org
Subject: RE: Newbie questions - database calls and caching data

Simon,

"If you're using session-scope backing beans, then you have to be *very*
careful about storing anything in members, as the memory will not be
released until the user session times out (or the user explicitly logs
out). This is generally not a good idea; request-scope beans +
t:saveState is much more elegant than session scope beans."

I would prefer to use a request-scope backing bean to store search results,
however, in order to support the datascroller, I need the data held in the
session.  The way my design works, when user enters search keywords, I
trigger a method on the backing bean to retrieve the data.  Then I store it
in a member variable of the backing bean (a datamodel) which is the data
list I access from the datatable tag.  From your message above, I will try
to see if I can use savestate instead of a session-backed bean - where does
savestate save the data - on the client or server?  In what form (a file)?

" saveState enables you to persist beans and values longer than request
scope, but shorter than session scope. It is ideal for persisting backing
beans and values with the same scope as your view components. It does this
by saving the target state with the component tree."

I am definitely concerned about memory usage with session state since my app
will have 100+ users performing searches.

Thanks
Tom

-----Original Message-----
From: Simon Kitching [mailto:skitching@apache.org] 
Sent: Sunday, January 08, 2006 4:11 AM
To: MyFaces Discussion
Subject: RE: Newbie questions - database calls and caching data

Hi,

I think the original question was really about *minimising* database
access, rather than how to implement the basic approach.

If the data being queried is really static, and small enough that you
can load it once into your webapp and keep it in memory, then you can
just store the data in a static member of some class. The getter
referenced from the h:dataTable component can then return that data
without any database access.

But if the data *can* change, then generally you do want to re-read it
from the database each time. And if the data is large and user-specific
(eg a list of the current user's emails) then you probably want to
re-read it on each request just to avoid using up too much memory.

There is a known issue where the data is fetched during the "validate"
phase, and then refetched again during the render phase. It's not a bug,
but can surprise people. The data is needed during validate because
there might be input fields, and those would need the old data in order
to determine if a ValueChangeEvent should be created. The data must be
refetched during rendering as the update model phase may have altered
the data to be displayed. So putting the database read in the get method
is reasonable; it really does need to be read twice in many cases.

If you have a request-scope backing bean, and you know the data doesn't
change between validate and render phases, then you can just read the
data the first time get is called, and cache it in a member of the
backing bean for use by later calls. This results in only one database
read per "cycle". When rendering is finished, the backing bean will of
course be discarded; a later postback will create a new one which will
then re-read the data on the first call to the getter.

If you're using session-scope backing beans, then you have to be *very*
careful about storing anything in members, as the memory will not be
released until the user session times out (or the user explicitly logs
out). This is generally not a good idea; request-scope beans +
t:saveState is much more elegant than session scope beans.

Whichever of the above you choose, it really is the getter method that
triggers the reading of the data in one way or another. If the backing
bean is request-scope then I guess you could also do the read during
backing bean initialisation, but I don't really see the point of that.

I vaguely remember someone noting that Shale has utilities to help
managed database access, but don't know much about that.

Regards,

Simon


On Sat, 2006-01-07 at 23:23 -0500, Tom Butler wrote:
> Chapter 10 within 'Core Java Server Faces' (david geary) covers
> database access - that may be a good place to start, especially if you
> are using Tomcat since that is the web container used in the examples
> - this chapter describes connection pooling which is useful if you
> have multiple users.
> 
>  
> 
> Your other questions really get more into design issues, and are
> subjective based on your specific application.
> 
>  
> 
> Here's the general approach I'm using that involves a search example,
> however, its straightforward because I do not require database update
> for this functionality (i.e., search only, no update back to
> database):
> 
>  
> 
>      1. create search form on .jsp (or .jsf) page
>      2. when search form is submitted, it calls an action on the form
>         bean
>      3. in this method, I grab a connection to the database (using a
>         method described in chapter 10 from the book above)
>      4. I have a bean object that represents the fields from the
>         database table I am reading
>      5. as I read through the database rows, I create a new instance
>         of the bean class, and add the columns from the database to
>         the attributes of the bean class object (using getter/setter
>         methods);  at the same time, after I populate the bean object
>         with the data from the database row, add the bean object to an
>         ArrayList (the arraylist will then contain a bean object for
>         each database row)
>      6. after I have read all of the rows, I disconnect from the
>         database and then wrap the ArrayList in a ListDataModel object
>         (which worked better for me with the tomahawk t:datatable
>         component);  Note at this point I'm disconnected from the
>         database and can use a java object to work with the data (of
>         course if you need to update the data, you'll need to modify
>         this solution.)
>      7.  The last step is that I use a Tomahawk T:datatable to display
>         the ListDataModel;  
> 
>  
> 
> Note I am newer to JSF/myfaces as well, so I'm not sure if this is a
> best practice, but this is what has worked for me.
> 
>  
> 
> Hope this helps.
> 
>  
> 
> Tom
> 
>  
> 
>                                    
> ______________________________________________________________________
> 
> From: Costa Basil [mailto:costa_basil@yahoo.ca] 
> Sent: Wednesday, January 04, 2006 1:46 PM
> To: users@myfaces.apache.org
> Subject: Newbie questions - database calls and caching data
> 
> 
>  
> 
> Hi
> 
> Where is the best place to make database calls to display lists or
> search results and how to cache them? How can I avoid making
> unecessary calls to the database?
> 
> Here are a two scenarios:
> 
> 1. Let's say I have a form where the user has to enter data and has to
> select data from a list or a combobox. The data in these lists come
> from various database small tables. What is the best place to make the
> database calls to extract the data for these lists? I looked at the cd
> catalog sample that comes with the blue print catalog samples, and the
> database calls are placed in the getXXX methods of the backing beans.
> Example:
> 
> public class AlbumView 
>   ...
> 
>     public List getTrackList() 
>         throws NamingException, SQLException
>     {
>         int currentId = getCurrentAlbum().getId();
>         if(cachedAlbumId != currentId) {
>             // If the album id was updated since our last query, query
> again
>             this.trackList = null;
>             this.trackCount = -1;
>         }
>         if(this.trackList == null) {
>             Connection connection = getConnection();
>             try {
>                 // Only query if we don't have the result cached for
> this request.
>                 ; PreparedStatement s =
> getConnection().prepareStatement( 
>                     "SELECT track, title FROM songs WHERE album_id
> = ?");
>                 s.setInt(1, currentId);
>                 ResultSet results = s.executeQuery();
>                 this.trackList = new ArrayList();
>                 while(results.next()) {
>                     TrackData track = new TrackData();
>                      track.setTrack(results.getInt("track"));
>                     track.setTitle(results.getString("title"));
>                     this.trackList.add(track);
>                 }
>                 this.cachedAlbumId = currentId;
>                 results.close();
>                 s.close();
>             } 
>             finally {
>                 connection.close();
>             }
>         }
>         return this.trackList;
>     }
> 
> and in the jsp page we have:
> 
>         <h:dataTable id="dataTable" border="1"
> value="#{AlbumView.trackList}" 
>                      var="track" rendered="#{AlbumView.trackCount >
> 0}">
>           <h:column>
> 
>         ...
> 
> The AlbumView is a backing bean:
>         
>   <managed-bean>
>     <description>
>     &n bsp; The backing bean for the album page
>     </description>
>     <managed-bean-name>AlbumView</managed-bean-name>
>     <managed-bean-class>
>       com.sun.j2ee.blueprints.cdcatalog.AlbumView
>     </managed-bean-class>
>     <managed-bean-scope>request</managed-bean-scope>
>   </managed-bean>
>   
>           
> What is not clear to me is the following. Let's say the user enters
> some invalid input and tries to save the data. Because there is some
> invalid input, then getTrackList will be called again next time the
> page is displayed. Right? What can I do in order in order to avoid
> that? I know the data in the track list doesn't change so when the
> page is re-displayed I don't want to requery the track list from the
> database.
> 
> Another problem that I see with this code is poor error handling. If
> the app bombs inside getTrackList probably the web application will
> jump to the jsp error page. Sometimes this is not desirable
> Overall, what is your opinion on getting the database data in these
> getXXX functions? Please ignore the fact that the jdbc calls are
> placed in the backing bean. 
> 
> 
> 2. Scenario 2
> 
> Searching stuff. Let's say I have a table with employees and I want to
> find employees by name. Assuming that the whole table with employees
> is not that big I want to cache the result of the search in memory. 
> In case the user opens a new search window, is there an easy way to
> avoid the clash of two search operations. Scenario: user enters
> criteria 1, clicks the search button, the app displays the search
> result, the user opens anther browser window, enters criteria 2,
> clicks search, the app displays the search result of criteria 2, the
> user moves to the first window, clicks next page, the app should
> display the second page of the first search.
> 
> 
> Any links to articles or sample applications on these topics are more
> than welcomed.
> 
> Thank you,
> 
> 
>                                    
> ______________________________________________________________________
> 
> Find your next car at Yahoo! Canada Autos
> 
> 


RE: Newbie questions - database calls and caching data

Posted by Tom Butler <to...@adelphia.net>.
Simon,

"If you're using session-scope backing beans, then you have to be *very*
careful about storing anything in members, as the memory will not be
released until the user session times out (or the user explicitly logs
out). This is generally not a good idea; request-scope beans +
t:saveState is much more elegant than session scope beans."

I would prefer to use a request-scope backing bean to store search results,
however, in order to support the datascroller, I need the data held in the
session.  The way my design works, when user enters search keywords, I
trigger a method on the backing bean to retrieve the data.  Then I store it
in a member variable of the backing bean (a datamodel) which is the data
list I access from the datatable tag.  From your message above, I will try
to see if I can use savestate instead of a session-backed bean - where does
savestate save the data - on the client or server?  In what form (a file)?

" saveState enables you to persist beans and values longer than request
scope, but shorter than session scope. It is ideal for persisting backing
beans and values with the same scope as your view components. It does this
by saving the target state with the component tree."

I am definitely concerned about memory usage with session state since my app
will have 100+ users performing searches.

Thanks
Tom

-----Original Message-----
From: Simon Kitching [mailto:skitching@apache.org] 
Sent: Sunday, January 08, 2006 4:11 AM
To: MyFaces Discussion
Subject: RE: Newbie questions - database calls and caching data

Hi,

I think the original question was really about *minimising* database
access, rather than how to implement the basic approach.

If the data being queried is really static, and small enough that you
can load it once into your webapp and keep it in memory, then you can
just store the data in a static member of some class. The getter
referenced from the h:dataTable component can then return that data
without any database access.

But if the data *can* change, then generally you do want to re-read it
from the database each time. And if the data is large and user-specific
(eg a list of the current user's emails) then you probably want to
re-read it on each request just to avoid using up too much memory.

There is a known issue where the data is fetched during the "validate"
phase, and then refetched again during the render phase. It's not a bug,
but can surprise people. The data is needed during validate because
there might be input fields, and those would need the old data in order
to determine if a ValueChangeEvent should be created. The data must be
refetched during rendering as the update model phase may have altered
the data to be displayed. So putting the database read in the get method
is reasonable; it really does need to be read twice in many cases.

If you have a request-scope backing bean, and you know the data doesn't
change between validate and render phases, then you can just read the
data the first time get is called, and cache it in a member of the
backing bean for use by later calls. This results in only one database
read per "cycle". When rendering is finished, the backing bean will of
course be discarded; a later postback will create a new one which will
then re-read the data on the first call to the getter.

If you're using session-scope backing beans, then you have to be *very*
careful about storing anything in members, as the memory will not be
released until the user session times out (or the user explicitly logs
out). This is generally not a good idea; request-scope beans +
t:saveState is much more elegant than session scope beans.

Whichever of the above you choose, it really is the getter method that
triggers the reading of the data in one way or another. If the backing
bean is request-scope then I guess you could also do the read during
backing bean initialisation, but I don't really see the point of that.

I vaguely remember someone noting that Shale has utilities to help
managed database access, but don't know much about that.

Regards,

Simon


On Sat, 2006-01-07 at 23:23 -0500, Tom Butler wrote:
> Chapter 10 within 'Core Java Server Faces' (david geary) covers
> database access - that may be a good place to start, especially if you
> are using Tomcat since that is the web container used in the examples
> - this chapter describes connection pooling which is useful if you
> have multiple users.
> 
>  
> 
> Your other questions really get more into design issues, and are
> subjective based on your specific application.
> 
>  
> 
> Here's the general approach I'm using that involves a search example,
> however, its straightforward because I do not require database update
> for this functionality (i.e., search only, no update back to
> database):
> 
>  
> 
>      1. create search form on .jsp (or .jsf) page
>      2. when search form is submitted, it calls an action on the form
>         bean
>      3. in this method, I grab a connection to the database (using a
>         method described in chapter 10 from the book above)
>      4. I have a bean object that represents the fields from the
>         database table I am reading
>      5. as I read through the database rows, I create a new instance
>         of the bean class, and add the columns from the database to
>         the attributes of the bean class object (using getter/setter
>         methods);  at the same time, after I populate the bean object
>         with the data from the database row, add the bean object to an
>         ArrayList (the arraylist will then contain a bean object for
>         each database row)
>      6. after I have read all of the rows, I disconnect from the
>         database and then wrap the ArrayList in a ListDataModel object
>         (which worked better for me with the tomahawk t:datatable
>         component);  Note at this point I'm disconnected from the
>         database and can use a java object to work with the data (of
>         course if you need to update the data, you'll need to modify
>         this solution.)
>      7.  The last step is that I use a Tomahawk T:datatable to display
>         the ListDataModel;  
> 
>  
> 
> Note I am newer to JSF/myfaces as well, so I'm not sure if this is a
> best practice, but this is what has worked for me.
> 
>  
> 
> Hope this helps.
> 
>  
> 
> Tom
> 
>  
> 
>                                    
> ______________________________________________________________________
> 
> From: Costa Basil [mailto:costa_basil@yahoo.ca] 
> Sent: Wednesday, January 04, 2006 1:46 PM
> To: users@myfaces.apache.org
> Subject: Newbie questions - database calls and caching data
> 
> 
>  
> 
> Hi
> 
> Where is the best place to make database calls to display lists or
> search results and how to cache them? How can I avoid making
> unecessary calls to the database?
> 
> Here are a two scenarios:
> 
> 1. Let's say I have a form where the user has to enter data and has to
> select data from a list or a combobox. The data in these lists come
> from various database small tables. What is the best place to make the
> database calls to extract the data for these lists? I looked at the cd
> catalog sample that comes with the blue print catalog samples, and the
> database calls are placed in the getXXX methods of the backing beans.
> Example:
> 
> public class AlbumView 
>   ...
> 
>     public List getTrackList() 
>         throws NamingException, SQLException
>     {
>         int currentId = getCurrentAlbum().getId();
>         if(cachedAlbumId != currentId) {
>             // If the album id was updated since our last query, query
> again
>             this.trackList = null;
>             this.trackCount = -1;
>         }
>         if(this.trackList == null) {
>             Connection connection = getConnection();
>             try {
>                 // Only query if we don't have the result cached for
> this request.
>                 ; PreparedStatement s =
> getConnection().prepareStatement( 
>                     "SELECT track, title FROM songs WHERE album_id
> = ?");
>                 s.setInt(1, currentId);
>                 ResultSet results = s.executeQuery();
>                 this.trackList = new ArrayList();
>                 while(results.next()) {
>                     TrackData track = new TrackData();
>                      track.setTrack(results.getInt("track"));
>                     track.setTitle(results.getString("title"));
>                     this.trackList.add(track);
>                 }
>                 this.cachedAlbumId = currentId;
>                 results.close();
>                 s.close();
>             } 
>             finally {
>                 connection.close();
>             }
>         }
>         return this.trackList;
>     }
> 
> and in the jsp page we have:
> 
>         <h:dataTable id="dataTable" border="1"
> value="#{AlbumView.trackList}" 
>                      var="track" rendered="#{AlbumView.trackCount >
> 0}">
>           <h:column>
> 
>         ...
> 
> The AlbumView is a backing bean:
>         
>   <managed-bean>
>     <description>
>     &n bsp; The backing bean for the album page
>     </description>
>     <managed-bean-name>AlbumView</managed-bean-name>
>     <managed-bean-class>
>       com.sun.j2ee.blueprints.cdcatalog.AlbumView
>     </managed-bean-class>
>     <managed-bean-scope>request</managed-bean-scope>
>   </managed-bean>
>   
>           
> What is not clear to me is the following. Let's say the user enters
> some invalid input and tries to save the data. Because there is some
> invalid input, then getTrackList will be called again next time the
> page is displayed. Right? What can I do in order in order to avoid
> that? I know the data in the track list doesn't change so when the
> page is re-displayed I don't want to requery the track list from the
> database.
> 
> Another problem that I see with this code is poor error handling. If
> the app bombs inside getTrackList probably the web application will
> jump to the jsp error page. Sometimes this is not desirable
> Overall, what is your opinion on getting the database data in these
> getXXX functions? Please ignore the fact that the jdbc calls are
> placed in the backing bean. 
> 
> 
> 2. Scenario 2
> 
> Searching stuff. Let's say I have a table with employees and I want to
> find employees by name. Assuming that the whole table with employees
> is not that big I want to cache the result of the search in memory. 
> In case the user opens a new search window, is there an easy way to
> avoid the clash of two search operations. Scenario: user enters
> criteria 1, clicks the search button, the app displays the search
> result, the user opens anther browser window, enters criteria 2,
> clicks search, the app displays the search result of criteria 2, the
> user moves to the first window, clicks next page, the app should
> display the second page of the first search.
> 
> 
> Any links to articles or sample applications on these topics are more
> than welcomed.
> 
> Thank you,
> 
> 
>                                    
> ______________________________________________________________________
> 
> Find your next car at Yahoo! Canada Autos
> 
> 


RE: Newbie questions - database calls and caching data

Posted by Costa Basil <co...@yahoo.ca>.
Thank you all for your input.

Yee CN <ye...@streamyx.com> wrote: Simon,

Thanks for the clarifications. Can you create a Wiki for this?

Regards,
Yee

-----Original Message-----
From: Simon Kitching [mailto:skitching@apache.org] 
Sent: Sunday, 8 January 2006 5:11 PM
To: MyFaces Discussion
Subject: RE: Newbie questions - database calls and caching data

Hi,

I think the original question was really about *minimising* database
access, rather than how to implement the basic approach.

If the data being queried is really static, and small enough that you
can load it once into your webapp and keep it in memory, then you can
just store the data in a static member of some class. The getter
referenced from the h:dataTable component can then return that data
without any database access.

But if the data *can* change, then generally you do want to re-read it
from the database each time. And if the data is large and user-specific
(eg a list of the current user's emails) then you probably want to
re-read it on each request just to avoid using up too much memory.

There is a known issue where the data is fetched during the "validate"
phase, and then refetched again during the render phase. It's not a bug,
but can surprise people. The data is needed during validate because
there might be input fields, and those would need the old data in order
to determine if a ValueChangeEvent should be created. The data must be
refetched during rendering as the update model phase may have altered
the data to be displayed. So putting the database read in the get method
is reasonable; it really does need to be read twice in many cases.

If you have a request-scope backing bean, and you know the data doesn't
change between validate and render phases, then you can just read the
data the first time get is called, and cache it in a member of the
backing bean for use by later calls. This results in only one database
read per "cycle". When rendering is finished, the backing bean will of
course be discarded; a later postback will create a new one which will
then re-read the data on the first call to the getter.

If you're using session-scope backing beans, then you have to be *very*
careful about storing anything in members, as the memory will not be
released until the user session times out (or the user explicitly logs
out). This is generally not a good idea; request-scope beans +
t:saveState is much more elegant than session scope beans.

Whichever of the above you choose, it really is the getter method that
triggers the reading of the data in one way or another. If the backing
bean is request-scope then I guess you could also do the read during
backing bean initialisation, but I don't really see the point of that.

I vaguely remember someone noting that Shale has utilities to help
managed database access, but don't know much about that.

Regards,

Simon


On Sat, 2006-01-07 at 23:23 -0500, Tom Butler wrote:
> Chapter 10 within 'Core Java Server Faces' (david geary) covers
> database access - that may be a good place to start, especially if you
> are using Tomcat since that is the web container used in the examples
> - this chapter describes connection pooling which is useful if you
> have multiple users.
> 
>  
> 
> Your other questions really get more into design issues, and are
> subjective based on your specific application.
> 
>  
> 
> Here's the general approach I'm using that involves a search example,
> however, its straightforward because I do not require database update
> for this functionality (i.e., search only, no update back to
> database):
> 
>  
> 
>      1. create search form on .jsp (or .jsf) page
>      2. when search form is submitted, it calls an action on the form
>         bean
>      3. in this method, I grab a connection to the database (using a
>         method described in chapter 10 from the book above)
>      4. I have a bean object that represents the fields from the
>         database table I am reading
>      5. as I read through the database rows, I create a new instance
>         of the bean class, and add the columns from the database to
>         the attributes of the bean class object (using getter/setter
>         methods);  at the same time, after I populate the bean object
>         with the data from the database row, add the bean object to an
>         ArrayList (the arraylist will then contain a bean object for
>         each database row)
>      6. after I have read all of the rows, I disconnect from the
>         database and then wrap the ArrayList in a ListDataModel object
>         (which worked better for me with the tomahawk t:datatable
>         component);  Note at this point I'm disconnected from the
>         database and can use a java object to work with the data (of
>         course if you need to update the data, you'll need to modify
>         this solution.)
>      7.  The last step is that I use a Tomahawk T:datatable to display
>         the ListDataModel;  
> 
>  
> 
> Note I am newer to JSF/myfaces as well, so I'm not sure if this is a
> best practice, but this is what has worked for me.
> 
>  
> 
> Hope this helps.
> 
>  
> 
> Tom
> 
>  
> 
>                                    
> ______________________________________________________________________
> 
> From: Costa Basil [mailto:costa_basil@yahoo.ca] 
> Sent: Wednesday, January 04, 2006 1:46 PM
> To: users@myfaces.apache.org
> Subject: Newbie questions - database calls and caching data
> 
> 
>  
> 
> Hi
> 
> Where is the best place to make database calls to display lists or
> search results and how to cache them? How can I avoid making
> unecessary calls to the database?
> 
> Here are a two scenarios:
> 
> 1. Let's say I have a form where the user has to enter data and has to
> select data from a list or a combobox. The data in these lists come
> from various database small tables. What is the best place to make the
> database calls to extract the data for these lists? I looked at the cd
> catalog sample that comes with the blue print catalog samples, and the
> database calls are placed in the getXXX methods of the backing beans.
> Example:
> 
> public class AlbumView 
>   ...
> 
>     public List getTrackList() 
>         throws NamingException, SQLException
>     {
>         int currentId = getCurrentAlbum().getId();
>         if(cachedAlbumId != currentId) {
>             // If the album id was updated since our last query, query
> again
>             this.trackList = null;
>             this.trackCount = -1;
>         }
>         if(this.trackList == null) {
>             Connection connection = getConnection();
>             try {
>                 // Only query if we don't have the result cached for
> this request.
>                 ; PreparedStatement s =
> getConnection().prepareStatement( 
>                     "SELECT track, title FROM songs WHERE album_id
> = ?");
>                 s.setInt(1, currentId);
>                 ResultSet results = s.executeQuery();
>                 this.trackList = new ArrayList();
>                 while(results.next()) {
>                     TrackData track = new TrackData();
>                      track.setTrack(results.getInt("track"));
>                     track.setTitle(results.getString("title"));
>                     this.trackList.add(track);
>                 }
>                 this.cachedAlbumId = currentId;
>                 results.close();
>                 s.close();
>             } 
>             finally {
>                 connection.close();
>             }
>         }
>         return this.trackList;
>     }
> 
> and in the jsp page we have:
> 
>         
> value="#{AlbumView.trackList}" 
>                      var="track" rendered="#{AlbumView.trackCount >
> 0}">
>           
> 
>         ...
> 
> The AlbumView is a backing bean:
>         
>   
>     
>     &n bsp; The backing bean for the album page
>     
>     AlbumView
>     
>       com.sun.j2ee.blueprints.cdcatalog.AlbumView
>     
>     request
>   
>   
>           
> What is not clear to me is the following. Let's say the user enters
> some invalid input and tries to save the data. Because there is some
> invalid input, then getTrackList will be called again next time the
> page is displayed. Right? What can I do in order in order to avoid
> that? I know the data in the track list doesn't change so when the
> page is re-displayed I don't want to requery the track list from the
> database.
> 
> Another problem that I see with this code is poor error handling. If
> the app bombs inside getTrackList probably the web application will
> jump to the jsp error page. Sometimes this is not desirable
> Overall, what is your opinion on getting the database data in these
> getXXX functions? Please ignore the fact that the jdbc calls are
> placed in the backing bean. 
> 
> 
> 2. Scenario 2
> 
> Searching stuff. Let's say I have a table with employees and I want to
> find employees by name. Assuming that the whole table with employees
> is not that big I want to cache the result of the search in memory. 
> In case the user opens a new search window, is there an easy way to
> avoid the clash of two search operations. Scenario: user enters
> criteria 1, clicks the search button, the app displays the search
> result, the user opens anther browser window, enters criteria 2,
> clicks search, the app displays the search result of criteria 2, the
> user moves to the first window, clicks next page, the app should
> display the second page of the first search.
> 
> 
> Any links to articles or sample applications on these topics are more
> than welcomed.
> 
> Thank you,
> 
> 
>                                    
> ______________________________________________________________________
> 
> Find your next car at Yahoo! Canada Autos
> 
> 




		
---------------------------------
Find your next car at Yahoo! Canada Autos

RE: Newbie questions - database calls and caching data

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

Thanks for the clarifications. Can you create a Wiki for this?

Regards,
Yee

-----Original Message-----
From: Simon Kitching [mailto:skitching@apache.org] 
Sent: Sunday, 8 January 2006 5:11 PM
To: MyFaces Discussion
Subject: RE: Newbie questions - database calls and caching data

Hi,

I think the original question was really about *minimising* database
access, rather than how to implement the basic approach.

If the data being queried is really static, and small enough that you
can load it once into your webapp and keep it in memory, then you can
just store the data in a static member of some class. The getter
referenced from the h:dataTable component can then return that data
without any database access.

But if the data *can* change, then generally you do want to re-read it
from the database each time. And if the data is large and user-specific
(eg a list of the current user's emails) then you probably want to
re-read it on each request just to avoid using up too much memory.

There is a known issue where the data is fetched during the "validate"
phase, and then refetched again during the render phase. It's not a bug,
but can surprise people. The data is needed during validate because
there might be input fields, and those would need the old data in order
to determine if a ValueChangeEvent should be created. The data must be
refetched during rendering as the update model phase may have altered
the data to be displayed. So putting the database read in the get method
is reasonable; it really does need to be read twice in many cases.

If you have a request-scope backing bean, and you know the data doesn't
change between validate and render phases, then you can just read the
data the first time get is called, and cache it in a member of the
backing bean for use by later calls. This results in only one database
read per "cycle". When rendering is finished, the backing bean will of
course be discarded; a later postback will create a new one which will
then re-read the data on the first call to the getter.

If you're using session-scope backing beans, then you have to be *very*
careful about storing anything in members, as the memory will not be
released until the user session times out (or the user explicitly logs
out). This is generally not a good idea; request-scope beans +
t:saveState is much more elegant than session scope beans.

Whichever of the above you choose, it really is the getter method that
triggers the reading of the data in one way or another. If the backing
bean is request-scope then I guess you could also do the read during
backing bean initialisation, but I don't really see the point of that.

I vaguely remember someone noting that Shale has utilities to help
managed database access, but don't know much about that.

Regards,

Simon


On Sat, 2006-01-07 at 23:23 -0500, Tom Butler wrote:
> Chapter 10 within 'Core Java Server Faces' (david geary) covers
> database access - that may be a good place to start, especially if you
> are using Tomcat since that is the web container used in the examples
> - this chapter describes connection pooling which is useful if you
> have multiple users.
> 
>  
> 
> Your other questions really get more into design issues, and are
> subjective based on your specific application.
> 
>  
> 
> Here's the general approach I'm using that involves a search example,
> however, its straightforward because I do not require database update
> for this functionality (i.e., search only, no update back to
> database):
> 
>  
> 
>      1. create search form on .jsp (or .jsf) page
>      2. when search form is submitted, it calls an action on the form
>         bean
>      3. in this method, I grab a connection to the database (using a
>         method described in chapter 10 from the book above)
>      4. I have a bean object that represents the fields from the
>         database table I am reading
>      5. as I read through the database rows, I create a new instance
>         of the bean class, and add the columns from the database to
>         the attributes of the bean class object (using getter/setter
>         methods);  at the same time, after I populate the bean object
>         with the data from the database row, add the bean object to an
>         ArrayList (the arraylist will then contain a bean object for
>         each database row)
>      6. after I have read all of the rows, I disconnect from the
>         database and then wrap the ArrayList in a ListDataModel object
>         (which worked better for me with the tomahawk t:datatable
>         component);  Note at this point I'm disconnected from the
>         database and can use a java object to work with the data (of
>         course if you need to update the data, you'll need to modify
>         this solution.)
>      7.  The last step is that I use a Tomahawk T:datatable to display
>         the ListDataModel;  
> 
>  
> 
> Note I am newer to JSF/myfaces as well, so I'm not sure if this is a
> best practice, but this is what has worked for me.
> 
>  
> 
> Hope this helps.
> 
>  
> 
> Tom
> 
>  
> 
>                                    
> ______________________________________________________________________
> 
> From: Costa Basil [mailto:costa_basil@yahoo.ca] 
> Sent: Wednesday, January 04, 2006 1:46 PM
> To: users@myfaces.apache.org
> Subject: Newbie questions - database calls and caching data
> 
> 
>  
> 
> Hi
> 
> Where is the best place to make database calls to display lists or
> search results and how to cache them? How can I avoid making
> unecessary calls to the database?
> 
> Here are a two scenarios:
> 
> 1. Let's say I have a form where the user has to enter data and has to
> select data from a list or a combobox. The data in these lists come
> from various database small tables. What is the best place to make the
> database calls to extract the data for these lists? I looked at the cd
> catalog sample that comes with the blue print catalog samples, and the
> database calls are placed in the getXXX methods of the backing beans.
> Example:
> 
> public class AlbumView 
>   ...
> 
>     public List getTrackList() 
>         throws NamingException, SQLException
>     {
>         int currentId = getCurrentAlbum().getId();
>         if(cachedAlbumId != currentId) {
>             // If the album id was updated since our last query, query
> again
>             this.trackList = null;
>             this.trackCount = -1;
>         }
>         if(this.trackList == null) {
>             Connection connection = getConnection();
>             try {
>                 // Only query if we don't have the result cached for
> this request.
>                 ; PreparedStatement s =
> getConnection().prepareStatement( 
>                     "SELECT track, title FROM songs WHERE album_id
> = ?");
>                 s.setInt(1, currentId);
>                 ResultSet results = s.executeQuery();
>                 this.trackList = new ArrayList();
>                 while(results.next()) {
>                     TrackData track = new TrackData();
>                      track.setTrack(results.getInt("track"));
>                     track.setTitle(results.getString("title"));
>                     this.trackList.add(track);
>                 }
>                 this.cachedAlbumId = currentId;
>                 results.close();
>                 s.close();
>             } 
>             finally {
>                 connection.close();
>             }
>         }
>         return this.trackList;
>     }
> 
> and in the jsp page we have:
> 
>         <h:dataTable id="dataTable" border="1"
> value="#{AlbumView.trackList}" 
>                      var="track" rendered="#{AlbumView.trackCount >
> 0}">
>           <h:column>
> 
>         ...
> 
> The AlbumView is a backing bean:
>         
>   <managed-bean>
>     <description>
>     &n bsp; The backing bean for the album page
>     </description>
>     <managed-bean-name>AlbumView</managed-bean-name>
>     <managed-bean-class>
>       com.sun.j2ee.blueprints.cdcatalog.AlbumView
>     </managed-bean-class>
>     <managed-bean-scope>request</managed-bean-scope>
>   </managed-bean>
>   
>           
> What is not clear to me is the following. Let's say the user enters
> some invalid input and tries to save the data. Because there is some
> invalid input, then getTrackList will be called again next time the
> page is displayed. Right? What can I do in order in order to avoid
> that? I know the data in the track list doesn't change so when the
> page is re-displayed I don't want to requery the track list from the
> database.
> 
> Another problem that I see with this code is poor error handling. If
> the app bombs inside getTrackList probably the web application will
> jump to the jsp error page. Sometimes this is not desirable
> Overall, what is your opinion on getting the database data in these
> getXXX functions? Please ignore the fact that the jdbc calls are
> placed in the backing bean. 
> 
> 
> 2. Scenario 2
> 
> Searching stuff. Let's say I have a table with employees and I want to
> find employees by name. Assuming that the whole table with employees
> is not that big I want to cache the result of the search in memory. 
> In case the user opens a new search window, is there an easy way to
> avoid the clash of two search operations. Scenario: user enters
> criteria 1, clicks the search button, the app displays the search
> result, the user opens anther browser window, enters criteria 2,
> clicks search, the app displays the search result of criteria 2, the
> user moves to the first window, clicks next page, the app should
> display the second page of the first search.
> 
> 
> Any links to articles or sample applications on these topics are more
> than welcomed.
> 
> Thank you,
> 
> 
>                                    
> ______________________________________________________________________
> 
> Find your next car at Yahoo! Canada Autos
> 
> 


RE: Newbie questions - database calls and caching data

Posted by Simon Kitching <sk...@apache.org>.
Hi,

I think the original question was really about *minimising* database
access, rather than how to implement the basic approach.

If the data being queried is really static, and small enough that you
can load it once into your webapp and keep it in memory, then you can
just store the data in a static member of some class. The getter
referenced from the h:dataTable component can then return that data
without any database access.

But if the data *can* change, then generally you do want to re-read it
from the database each time. And if the data is large and user-specific
(eg a list of the current user's emails) then you probably want to
re-read it on each request just to avoid using up too much memory.

There is a known issue where the data is fetched during the "validate"
phase, and then refetched again during the render phase. It's not a bug,
but can surprise people. The data is needed during validate because
there might be input fields, and those would need the old data in order
to determine if a ValueChangeEvent should be created. The data must be
refetched during rendering as the update model phase may have altered
the data to be displayed. So putting the database read in the get method
is reasonable; it really does need to be read twice in many cases.

If you have a request-scope backing bean, and you know the data doesn't
change between validate and render phases, then you can just read the
data the first time get is called, and cache it in a member of the
backing bean for use by later calls. This results in only one database
read per "cycle". When rendering is finished, the backing bean will of
course be discarded; a later postback will create a new one which will
then re-read the data on the first call to the getter.

If you're using session-scope backing beans, then you have to be *very*
careful about storing anything in members, as the memory will not be
released until the user session times out (or the user explicitly logs
out). This is generally not a good idea; request-scope beans +
t:saveState is much more elegant than session scope beans.

Whichever of the above you choose, it really is the getter method that
triggers the reading of the data in one way or another. If the backing
bean is request-scope then I guess you could also do the read during
backing bean initialisation, but I don't really see the point of that.

I vaguely remember someone noting that Shale has utilities to help
managed database access, but don't know much about that.

Regards,

Simon


On Sat, 2006-01-07 at 23:23 -0500, Tom Butler wrote:
> Chapter 10 within ‘Core Java Server Faces’ (david geary) covers
> database access – that may be a good place to start, especially if you
> are using Tomcat since that is the web container used in the examples
> – this chapter describes connection pooling which is useful if you
> have multiple users.
> 
>  
> 
> Your other questions really get more into design issues, and are
> subjective based on your specific application.
> 
>  
> 
> Here’s the general approach I’m using that involves a search example,
> however, its straightforward because I do not require database update
> for this functionality (i.e., search only, no update back to
> database):
> 
>  
> 
>      1. create search form on .jsp (or .jsf) page
>      2. when search form is submitted, it calls an action on the form
>         bean
>      3. in this method, I grab a connection to the database (using a
>         method described in chapter 10 from the book above)
>      4. I have a bean object that represents the fields from the
>         database table I am reading
>      5. as I read through the database rows, I create a new instance
>         of the bean class, and add the columns from the database to
>         the attributes of the bean class object (using getter/setter
>         methods);  at the same time, after I populate the bean object
>         with the data from the database row, add the bean object to an
>         ArrayList (the arraylist will then contain a bean object for
>         each database row)
>      6. after I have read all of the rows, I disconnect from the
>         database and then wrap the ArrayList in a ListDataModel object
>         (which worked better for me with the tomahawk t:datatable
>         component);  Note at this point I’m disconnected from the
>         database and can use a java object to work with the data (of
>         course if you need to update the data, you’ll need to modify
>         this solution.)
>      7.  The last step is that I use a Tomahawk T:datatable to display
>         the ListDataModel;  
> 
>  
> 
> Note I am newer to JSF/myfaces as well, so I’m not sure if this is a
> best practice, but this is what has worked for me.
> 
>  
> 
> Hope this helps.
> 
>  
> 
> Tom
> 
>  
> 
>                                    
> ______________________________________________________________________
> 
> From: Costa Basil [mailto:costa_basil@yahoo.ca] 
> Sent: Wednesday, January 04, 2006 1:46 PM
> To: users@myfaces.apache.org
> Subject: Newbie questions - database calls and caching data
> 
> 
>  
> 
> Hi
> 
> Where is the best place to make database calls to display lists or
> search results and how to cache them? How can I avoid making
> unecessary calls to the database?
> 
> Here are a two scenarios:
> 
> 1. Let's say I have a form where the user has to enter data and has to
> select data from a list or a combobox. The data in these lists come
> from various database small tables. What is the best place to make the
> database calls to extract the data for these lists? I looked at the cd
> catalog sample that comes with the blue print catalog samples, and the
> database calls are placed in the getXXX methods of the backing beans.
> Example:
> 
> public class AlbumView 
>   ...
> 
>     public List getTrackList() 
>         throws NamingException, SQLException
>     {
>         int currentId = getCurrentAlbum().getId();
>         if(cachedAlbumId != currentId) {
>             // If the album id was updated since our last query, query
> again
>             this.trackList = null;
>             this.trackCount = -1;
>         }
>         if(this.trackList == null) {
>             Connection connection = getConnection();
>             try {
>                 // Only query if we don't have the result cached for
> this request.
>                 ; PreparedStatement s =
> getConnection().prepareStatement( 
>                     "SELECT track, title FROM songs WHERE album_id
> = ?");
>                 s.setInt(1, currentId);
>                 ResultSet results = s.executeQuery();
>                 this.trackList = new ArrayList();
>                 while(results.next()) {
>                     TrackData track = new TrackData();
>                      track.setTrack(results.getInt("track"));
>                     track.setTitle(results.getString("title"));
>                     this.trackList.add(track);
>                 }
>                 this.cachedAlbumId = currentId;
>                 results.close();
>                 s.close();
>             } 
>             finally {
>                 connection.close();
>             }
>         }
>         return this.trackList;
>     }
> 
> and in the jsp page we have:
> 
>         <h:dataTable id="dataTable" border="1"
> value="#{AlbumView.trackList}" 
>                      var="track" rendered="#{AlbumView.trackCount >
> 0}">
>           <h:column>
> 
>         ...
> 
> The AlbumView is a backing bean:
>         
>   <managed-bean>
>     <description>
>     &n bsp; The backing bean for the album page
>     </description>
>     <managed-bean-name>AlbumView</managed-bean-name>
>     <managed-bean-class>
>       com.sun.j2ee.blueprints.cdcatalog.AlbumView
>     </managed-bean-class>
>     <managed-bean-scope>request</managed-bean-scope>
>   </managed-bean>
>   
>           
> What is not clear to me is the following. Let's say the user enters
> some invalid input and tries to save the data. Because there is some
> invalid input, then getTrackList will be called again next time the
> page is displayed. Right? What can I do in order in order to avoid
> that? I know the data in the track list doesn't change so when the
> page is re-displayed I don't want to requery the track list from the
> database.
> 
> Another problem that I see with this code is poor error handling. If
> the app bombs inside getTrackList probably the web application will
> jump to the jsp error page. Sometimes this is not desirable
> Overall, what is your opinion on getting the database data in these
> getXXX functions? Please ignore the fact that the jdbc calls are
> placed in the backing bean. 
> 
> 
> 2. Scenario 2
> 
> Searching stuff. Let's say I have a table with employees and I want to
> find employees by name. Assuming that the whole table with employees
> is not that big I want to cache the result of the search in memory. 
> In case the user opens a new search window, is there an easy way to
> avoid the clash of two search operations. Scenario: user enters
> criteria 1, clicks the search button, the app displays the search
> result, the user opens anther browser window, enters criteria 2,
> clicks search, the app displays the search result of criteria 2, the
> user moves to the first window, clicks next page, the app should
> display the second page of the first search.
> 
> 
> Any links to articles or sample applications on these topics are more
> than welcomed.
> 
> Thank you,
> 
> 
>                                    
> ______________________________________________________________________
> 
> Find your next car at Yahoo! Canada Autos
> 
> 


RE: Newbie questions - database calls and caching data

Posted by Tom Butler <to...@adelphia.net>.
Chapter 10 within 'Core Java Server Faces' (david geary) covers database
access - that may be a good place to start, especially if you are using
Tomcat since that is the web container used in the examples - this chapter
describes connection pooling which is useful if you have multiple users.

 

Your other questions really get more into design issues, and are subjective
based on your specific application.

 

Here's the general approach I'm using that involves a search example,
however, its straightforward because I do not require database update for
this functionality (i.e., search only, no update back to database):

 

1.	create search form on .jsp (or .jsf) page
2.	when search form is submitted, it calls an action on the form bean
3.	in this method, I grab a connection to the database (using a method
described in chapter 10 from the book above)
4.	I have a bean object that represents the fields from the database
table I am reading
5.	as I read through the database rows, I create a new instance of the
bean class, and add the columns from the database to the attributes of the
bean class object (using getter/setter methods);  at the same time, after I
populate the bean object with the data from the database row, add the bean
object to an ArrayList (the arraylist will then contain a bean object for
each database row)
6.	after I have read all of the rows, I disconnect from the database
and then wrap the ArrayList in a ListDataModel object (which worked better
for me with the tomahawk t:datatable component);  Note at this point I'm
disconnected from the database and can use a java object to work with the
data (of course if you need to update the data, you'll need to modify this
solution.)
7.	 The last step is that I use a Tomahawk T:datatable to display the
ListDataModel;  

 

Note I am newer to JSF/myfaces as well, so I'm not sure if this is a best
practice, but this is what has worked for me.

 

Hope this helps.

 

Tom

 

  _____  

From: Costa Basil [mailto:costa_basil@yahoo.ca] 
Sent: Wednesday, January 04, 2006 1:46 PM
To: users@myfaces.apache.org
Subject: Newbie questions - database calls and caching data

 

Hi

Where is the best place to make database calls to display lists or search
results and how to cache them? How can I avoid making unecessary calls to
the database?

Here are a two scenarios:

1. Let's say I have a form where the user has to enter data and has to
select data from a list or a combobox. The data in these lists come from
various database small tables. What is the best place to make the database
calls to extract the data for these lists? I looked at the cd catalog sample
that comes with the blue print catalog samples, and the database calls are
placed in the getXXX methods of the backing beans. Example:

public class AlbumView 
  ...

    public List getTrackList() 
        throws NamingException, SQLException
    {
        int currentId = getCurrentAlbum().getId();
        if(cachedAlbumId != currentId) {
            // If the album id was updated since our last query, query again
            this.trackList = null;
            this.trackCount = -1;
        }
        if(this.trackList == null) {
            Connection connection = getConnection();
            try {
                // Only query if we don't have the result cached for this
request.
                ; PreparedStatement s = getConnection().prepareStatement( 
                    "SELECT track, title FROM songs WHERE album_id = ?");
                s.setInt(1, currentId);
                ResultSet results = s.executeQuery();
                this.trackList = new ArrayList();
                while(results.next()) {
                    TrackData track = new TrackData();
                     track.setTrack(results.getInt("track"));
                    track.setTitle(results.getString("title"));
                    this.trackList.add(track);
                }
                this.cachedAlbumId = currentId;
                results.close();
                s.close();
            } 
            finally {
                connection.close();
            }
        }
        return this.trackList;
    }

and in the jsp page we have:

        <h:dataTable id="dataTable" border="1"
value="#{AlbumView.trackList}" 
                     var="track" rendered="#{AlbumView.trackCount > 0}">
          <h:column>

        ...

The AlbumView is a backing bean:
        
  <managed-bean>
    <description>
    &n bsp; The backing bean for the album page
    </description>
    <managed-bean-name>AlbumView</managed-bean-name>
    <managed-bean-class>
      com.sun.j2ee.blueprints.cdcatalog.AlbumView
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>
  
          
What is not clear to me is the following. Let's say the user enters some
invalid input and tries to save the data. Because there is some invalid
input, then getTrackList will be called again next time the page is
displayed. Right? What can I do in order in order to avoid that? I know the
data in the track list doesn't change so when the page is re-displayed I
don't want to requery the track list from the database.

Another problem that I see with this code is poor error handling. If the app
bombs inside getTrackList probably the web application will jump to the jsp
error page. Sometimes this is not desirable
Overall, what is your opinion on getting the database data in these getXXX
functions? Please ignore the fact that the jdbc calls are placed in the
backing bean. 


2. Scenario 2

Searching stuff. Let's say I have a table with employees and I want to find
employees by name. Assuming that the whole table with employees is not that
big I want to cache the result of the search in memory. 
In case the user opens a new search window, is there an easy way to avoid
the clash of two search operations. Scenario: user enters criteria 1, clicks
the search button, the app displays the search result, the user opens anther
browser window, enters criteria 2, clicks search, the app displays the
search result of criteria 2, the user moves to the first window, clicks next
page, the app should display the second page of the first search.


Any links to articles or sample applications on these topics are more than
welcomed.

Thank you,

  _____  

Find your next car at  <http://autos.yahoo.ca> Yahoo! Canada Autos