It is probably a kind of architectural question, but still it has to have a 'best practice solution' or an accepted standard.
I am talking about some kind of static data that needs to be displayed on site, like catalogue of products, list of menus and menu items, list of breadcrumb blocks etc. This option is available when using any standard CMS, I suppose.
But I would like to use a pure JSF solution for this issue.
So, to get back to the question, my elaborations stem upon the following principles:
Data shouldn't be hardcoded in facelets, hence I use database to hold the values, like in the following db script (MYSQL in my case):
CREATE TABLE CatalogueGroup (
CatalogueGroupName VARCHAR(100) NOT NULL PRIMARY KEY,
URLPath VARCHAR(200) NOT NULL,
ParentGroupName VARCHAR(100) DEFAULT NULL,
FOREIGN KEY (ParentGroupName) REFERENCES CatalogueGroup(CatalogueGroupName) ON UPDATE CASCADE ON DELETE SET NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
I would then like to use the entity class to be held in a @ManagedBean and display it in a view, like
public class CatalogueGroup implements Serializable {
private String catalogueGroupName;
private List<CatalogueGroup> children = new ArrayList<CatalogueGroup>();
private CatalogueGroup parentGroup;
//other stuff of this bean
}
@ManagedBean
@SessionScoped
public class CatalogueBean implements Serializable {
private CatalogueGroup catalogue;//loaded via CatalogueGroupDAO with condition parentGroup == null
//other stuff of this bean
}
//snippet of xhtml view for a two-level catalogue
<ul><h:outputText value="#{catalogueBean.catalogue.catalogueGroupName}" />
<ui:rereat value="#{catalogueBean.catalogue.children}" var="group">
<li><h:outputText value="#{group.catalogueGroupName}" /></li>
</ui:repeat>
</ul>
The abovementioned setup works, but it feels like it is an awkward one. So, I would like to raise the following open, 'best practice' questions to the jsf community:
@SessionScope
bean that will be loaded once and redisplayed on every view or@RequestScoped
bean that will access database on every page display.@RequestScoped
bean only;Very interesting but maybe so open fielded question.
First of all the scope depends on which utility you will give to your catalog. I suggest you to go through @ViewScoped
if you want to link the data to a particular view or @SessionScoped
if your aim is to implement something like a shopping basket.
For the recursive functions I think you should avoid that kind of practice in pure view (xhtml) layer and use a library like Primefaces or Richfaces which have built-in component for what you want to do. Using them you only have to take care of their logical structure programatically inside your managed backing bean.
Finally, for catalog limitations, I suggest you to load only what you are going to use from the database. In that way you are not overloading neither the server-database or the server-client connections. You can have a @SessionScoped
bean which manages current logged user's session and depending on that you can ask the database for some values or others.
Also you have to take care about your catalog, if you are doing a lot of modifications on it during the session, maybe @ViewScoped
bean is a better choice, because it will be realoaded each time view is requested. If you use @SessionScoped
bean for that you have to manually add each change on it, in order to maintain it updated during the session.
"load the whole catalogue and limit its children in views with rendered=false"
That's a work you don't have to do if you do it the way I say. Conditionally evaluating each of the tree nodes can be a hell if you are managing a complex tree and introduces more logic into the view. Definitely you should avoid that as far as you can.
Even you have already reached a solution, that's my main idea about that.
You can use a cache to store the menus for various user roles. Then you either invalidate the cache when you insert new data in the database (if you insert this from an administration page) or you can set the cache to expire after a certain period (once a day, every few hours, etc.) and you read again the data when the cache expires.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With