• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Table Not Showing until Parameter Is Passed

 
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys,

I am having more trouble with JSF. I have three tables, two were created using dataTables and the third was created using ui:repeat as I was struggling to find an alternative that would enable me to get the layout I needed(headings along the left column instead of the top row, if you know of a better way I would welcome your suggestions). Anyway, my problem is, that the table made using ui:repeat isn't showing up until after the parameter has been passed to it and I want it to always be on show, even when it is empty.
Here is my code:
This is the bean


And here is my xhtml file:
 
Saloon Keeper
Posts: 27763
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One thing that isn't helping is that you are doing horrible things with the database.

When a JSF View request comes in, it's not uncommon for the property "get" methods to be invoked 5 or 6 times each.

Think about that. You are making the database request 5 or 6 times for every view request. All to return what should be the same data. And on top of that, you're not using a Database Connection pool, you're doing a brute-force Driver getConnection, which takes a lot longer than a typical pool getConnection request. This isn't something you want to do. If you have lots of users, the sixfold multiplier times the number of users can really add up, to say nothing of the connection overhead.

Then there's the other issue. "get" methods are supposed to be idempotent. That means that if you invoke the "get" method 6 times, you should get exactly the same set of rows in the exact same order each and every time. When you do a separate database read 6 times, there's a distinct risk that some other user or application inserts, deletes, or changes rows in the returned data. In fact, I can name one well-know database where the order of the returned rows could only be guaranteed to be repeatable to the degree that the "ORDER BY" clause of the SELECT required them to be.

I'd also give you grief for using a parameter on the View instead of a DataModel for the table, but you need to offload your database code first. Read it once and cache it.
 
Oli Brown
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So if I need to retrieve an entry from the database based on a particular clientID, I am supposed to have a separate get method for each entry? Without knowing how many entries there are? Or how many are going to be added in the future?

Edit: Forgot to thank you for the connection pool suggestion. Looking in to that now
 
Tim Holloway
Saloon Keeper
Posts: 27763
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Oli Brown wrote:So if I need to retrieve an entry from the database based on a particular clientID, I am supposed to have a separate get method for each entry? Without knowing how many entries there are? Or how many are going to be added in the future?



No. Absolutely not!

JSF has a set of Model wrapper classes for dataTables. They're all based off of javax.faces.DataModel. The most commonly-used ones are ListDataModel and ArrayDataModel, but there are others, and I even occasionally subclass the List and Array DataModel classes when it's useful to do so.

What a DataModel does is decorate your raw data (List, Array, or whatever) with some extra JSF-specific enhancements (cursor capabilities). You can then use the DataModel's getRowData() and getRowIndex() methods in your action method to determine precisely which table row was selected without either coding logic (parameters) on your View Template or implementing multiple action methods, one for each row.

If you pass a raw collection as the value of a dataTable tag, a DataModel is produced automatically, but it's an anonymous DataModel, and you have no way to access it to employ its cursor methods for your benefit. As a rule, I only recommend using raw data in a dataTable when you won't need those methods. Which is primarily when you're doing a simple display without any need to click on any of its rows. You don't save much effort by not supplying your own dataTable and don't expect things to be any more efficient if you lest JSF do it - the amount of work done by JSF itself is just about the same.

A DataModel wraps data. You can either pass in the wrapped data (List, array, or whatever) in its constructor, or you can set/update it via its setWrappedData() method. The 2 approaches are equivalent. Once wrapped, you don't have to do anything further to the DataModel. Changes to the wrapped data itself reflect automatically, so the only time you need to change it is if you're throwing away the original raw data and replacing it with an entirely new set of data.

In practical terms, since a DataModel is pretty low overhead, my typical method for triggering a (re)read of the raw data is to set my table's datamodel to null. My "get" method considers this as a trigger to load the appropriate raw data, wrap it, and cache the results as a new datamodel.

Incidentally, DataModels (whether explicit or implicit) are one reason why I say that "Request scope is almost 100% useless in JSF". The DataModel contains cursor information carried over from the last request/response cycle. If you use Request scope, that DataModel is destroyed and a new DataModel is constructed - but the cursor information is now gone.

DataModels are one also one of the few exceptions to my famous Rule #1 of JSF - the more javax.faces objects and code in your app, the more likely you're doing it wrong. The Model classes (DataModel and SelectItems) are helpers that allow the data that they present to remain as POJO constructs while augmenting them with essential JSF capabilities.
 
Oli Brown
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I didn't think so, that was just what I understood from your earlier reply.
EDIT: I have reread it and see how I misinterpreted it.
I will get to work on changing my code to use DataModels.
Thanks for all the help. I am not used to JSF so all of this is new to me.
 
Tim Holloway
Saloon Keeper
Posts: 27763
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Unfortunately, a LOT of people aren't used to DataModels.

I think that the ability to directly reference raw collections was an addition to JSF2 and that JSF1 required a DataModel. In any event, since then the world has been flooded with bad examples.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic