Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using jsf session scoped managed bean to represent static hierarchical data [closed]

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:

  1. 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;
    
  2. 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:

  1. What is a proper way of setting up a catalogue bean like this:
    • A @SessionScope bean that will be loaded once and redisplayed on every view or
    • A @RequestScoped bean that will access database on every page display.
  2. Is there a way to setup recursive functions in facelet view, or I should limit the catalogue nesting level to, say, 2 or 3.
  3. I would like to display some kind of modified catalogue, exposing more groups to the logged in users, depending on his role (column added in a database table) and display basic catalogue when no user logs in. Additionally, I would like to occasionally insert some new groups in the catalogue and not force users to re-log in, but redisplay proper data at once:
    • Shall I filter groups in business layer and expose a filtered CatalogueGroup to the bean, or I will load the whole catalogue and limit its children in views with rendered=false;
    • Is exposure of a whole catalogue in session a proper way to go;
    • Is it possible to send modification events on adding new database entries to all current CatalogueBean active on server forcing to refresh their properties (CatalogueGroup) or to achieve this functionality I need to use @RequestScoped bean only;
    • In case using request scoped bean is the only alternative will it be wise to access database to get data so often that rarely change or there is a smarter way of doing things;
    • When user logs in (and logs out) there is already an instance of session scoped catalogue, how to refresh it: do I need to manually do it in action/action listener or I need to invalidate session or do something more appropriate to the situation.
like image 787
skuntsel Avatar asked Nov 03 '22 11:11

skuntsel


2 Answers

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.

like image 96
Xtreme Biker Avatar answered Nov 15 '22 11:11

Xtreme Biker


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.

like image 24
Bogdan Avatar answered Nov 15 '22 12:11

Bogdan