Very common issue, Gurus, which one is better technique?
Most web applications present users with a list of data (lets call it master list), and users can click on an item from the list to view its detail and then update the detail. To implement this "two page master detail", we have many options to choose from, and I want to find out the best practices:
1. For master page, use a page-scope Data Provider and session-scope RowSet -- which is what JSC creates by default if you drag and drop Table component and then drag drop a table from Server > Data Sources.
2. Use a separate another DataProvider and RowSet for detail page and bind its text fields with the DataProvider fields. Use datProvider.commit() to save changes.
OR
For detail page, use the session-scope RowSet created for Step 1 and use detailDataProvider.setCursor () to move the cursor to the row user has clicked on the master page. This way, we don't have to create two rowsets (one for master and one for detail page)
OR
Use only one rowset for both master and detail and use setCommand to dynamically change the SQL query like this:
MasterRowSet().setCommand("SELECT * from customers WHERE customer_id="+id);
OR
There are a lot of other ways (for example using query strings to pass the ID from master to detail page and then search for that ID within the rowSet, etc.._
I am tryign to figure out what is the best practice in this very common situation that most developers come across.
Message was edited by:
Sabir
[1516 byte] By [
Sabir] at [2007-11-26 11:16:40]

# 1
Very well put question and one I'd like to see answered by a proper Guru! My own observation, for what it's worth: my current (live) app in which I started off using master and detail rowsets in the session bean has a very cluttered session bean and really hits the database hard at design time.
Later on in the development cycle I used rowsets and DPs located in the page bean (request scope) wherever possible and this seems to have been neater, better encapsulated, kinder on the database, and updates itself better to changes made by other users (without me having to run explict updates). Sure a well designed app could have a lot of these rowsets in the application scope and update them only as required but in the real world do you really want to get involved with this logic if your app is not going to be used by millions of people concurrently? And does one user need to see anothers updates instantly? Very seldom...
To summarize: I got good results from sticking the detail rowset and dp in the page bean. Everything I'm using is in 1 place and if I make a change to the query I'm not concerned that it might break some other part of my app. The ones I have in the session bean are irritating to track down and i'm not always 100 percent sure if modifing them is going to break something.
# 2
Thanks for your input. It seems cleaner to stick your detail rowset (RS) and associated dataProvider (DP) in page bean. This way you can change it without causing side-effects to other pages.
The only trade off, that I see, is that it will do a database query on every single time any user (across all sessions, and requests), will open that page. If you have rowset in session, then at least it does not execute a database query to pull the data for every single request -- unless you manually do a refresh() or execute(). All JSC tutorials and examples use DP is page bean and RS in session bean -- without explaining why they are doing it that way.
Do you use DP and RS on page bean for master page too?
Message was edited by:
Sabir
Sabir at 2007-7-7 3:31:44 >

# 3
I agree to stick your detail rowset (RS) and associated dataProvider (DP) in page bean.
# 4
I have a question on it:if i have 200 pages with 2 or more RS for page ( i have 500 / 1000 RS).I put all in sessionBean1 ?
# 5
I have the same concern. Creator Team, any guidance on this very common issue?
Also, in the tutorials, when user click on any row on the table in the master page, they alway save the primary key (i.e customer_id, user_id, part_id, etc.) of the clicked row in the sessionBean1 and then in the detail page, they use the stored primary key to find what record/row to display. Now, if you have dozens or hundreds of pages, that means you have to use lots of variables to store in the SessionBean1 -- like customer_id, part_id, this_id, that_id, etc., which will make it very cluttered. Is that the best approach? I am trying to get away from it and trying to use query string or just a generic property of the sessionBean (that I am calling data_id) and use the same one for all pages.
Is there any design pattern for JSC that can help for web applications where you have dozens of two-page master-detail cases?
Message was edited by:
Sabir
Sabir at 2007-7-7 3:31:44 >

# 6
Sabir,
I also got fed up with the ever increasing number on single use session bean properties being used to pass data between master and detail rowsets. My current solution is that od a generic stack implemented thus (in my session bean):
private Queue stack =new LinkedList();
/**
* Getter for property stack.
* @return Value of property stack.
*/
public Object getStack() {
if (stack.isEmpty()){getApplicationBean1().applog.severe("Session bean stack was empty but something asked for a Object");}
return stack.poll();
}
/**
* Setter for property stack.
* @param stack New value of property stack.
*/
public void setStack(Object item) {
stack.add(item);
}
I've also experimented with using a hidden field to maintain values between requests. Not sure if I like this approach yet, although it's well encapsulated and doesn't leave any footprint on your request bean.
Gurus: why the big silence?
# 7
This sounds an interesting way to do it. Not sure if its the best practice or optimal way. Can you please explain a bit on how are you actually using it on master-page. If you can copy paste the usage code too that will be great.Thanks
Sabir at 2007-7-7 3:31:44 >

# 8
So here's how I'd like to call the detail page from the master page:
public String button1_action() {
return "detailPage someId"; // ie detailPage(Object someId)
}
Now JSF doesn't work like this so I've tried everything I can think of:
properties in the session bean (session bean gets quite bulky and messy after a while)
properties in the sessionbean that set the parameters of the rowset (sessionbean scope) directly (this is a nightmare to debug! Don't do it!)
Setting the parameter in the rowset (sessionbean scope) (almost as bad as the previous method)
The stack example above was an approach i decided was not a bad idea as it accepts n parameters of any type and complies to my idea of how a program works. Ideally it ought to be rewritten so that setStack is "push" and getStack is "pop". So I use the stack to pass parameters to my detail table. But once passed thay have been removed from the stack and I need somewhere to store them while postback processing happens on my detail page. I used a hidden field: just dropped one on the page and added this to the Page init :
Object bookingId;
if (hiddenField1.getText()==null){ //first time this page has been inited
bookingId = getSessionBean1().getStack();
if (bookingId==null){
bookingId= new Integer(-1);
}
hiddenField1.setText(bookingId);
}
bookingId=hiddenField1.getText();
try{
bookingsRowSet.setObject(1,bookingId);
}catch (SQLException ex){
getApplicationBean1().applog.severe("SQL error looking up object "+
bookingId.toString()+ ex.getMessage());
}
I'm not sure if i like it; it's just something i tried. Personally I'd prefer it if i could just call the page with a parameter (I'm sure I can send one in http://url?param format but this is a security risk for my app)...
What I like about it is that once the user navigates away from the detail page everything is gone: the parameters in the sessionbean, the contents of the hidden field everything. Much less to trip over at a later stage...
Also I use one page for Add and Edit. This is a big saving...
