Populating "List" boxes - with rarely changing static data

Discussions

EJB design: Populating "List" boxes - with rarely changing static data

  1. I recently read in a thread about populating various static data in a "List" box. The idea was to use a singleton to read all static data from database and instantiate the singleton during start up of the application server. The List box values will be populated from this singleton (getter/setter methods).

    I have got the following questions regarding populating values in a LIST box :
    1) I beleive using direct DB access or via session beans is a costlier process, because for each web page with list box - db access is required. So this should be avoided at any cost. Is my concept acceptable ?
    2) What are the pros/cons if we access the data from DB once during startup and store the cache in the servletconetxt ? Once we store it servlet context it can be shared by all clients. Also any dynamic changes to "static data" can be added/updated to servlet context. Later when the server is shut down, the servlet context objects can be rewritten to database. This minimises the DB access, however if the static data is of large volume, may occupy lot of space in server. Please correct me if i am wrong.
    3) I read in lot of discussions that singleton's are illegal in EJB. But in scenario like this i think Singleton's suit best. Any thoughts ?
    4) In my application, i went along with the approach of storing static data in "singleton" object. I am using Orion as my application server. Unlike Weblogic this doesnot have a "load on startup" feature. However i can load a servlet on start up. So in my startup-servlet's init method i am instatiating the singleton and loading data. Then this singleton is used to populate all the list boxes. This works fine as long as the static data remain unchanged. What happens if i want to add some more new static data. When will this be loaded into singleton class ? Do i need to restart the server ?
    For eg: say in a Banking application, the account types are defined as static data. When i start my application server, i have only "ordinary account" as the only account type. After deploying the application, there is a new need to add "savings account" as a new account type. To have this listed in my web-pages, do i need to bring down my application server ? Or can i add it to the singleton object when new static data is added ? Please help me with your ideas.



    Please reply.
    regards
    sankar
  2. What to do when the static data in the List box depends on Locale?

    plz reply,
    Bharath
  3. Singletons are illegal (well, not in so many words, but should be avoided) because they are very non-portable, and tend to not be singletons at all. The issue is that most application servers use custom ClassLoaders outside the systems ClassLoader. This design in many application servers can lead to one singleton per ClassLoader, meaning you dont have a singleton at all. For this reason, most people suggest you avoid traditional singleton patterns.

    However, there is no reason you cant use a read-only static method as the cache. Section 18.1.2 bans static methods that are not write only, but in a cache like this you may find you only need to write the data one time, when it is first initialized. List of states in the US is a perfect example. Store the cache as a static final member, in say a Hashtable. Populate the Hashtable in a static initializer and then never do the query again, simply return the cached data from teh Hashtable.

    Dave Wolf
    Internet Applications Division
    Sybase
  4. Dave,
    Thanks for your reply. But i am not sure whether i understood your reply. I have written a template code - to express my understanding. Please confirm for correctness.

    Class A {
       private vector getStateList() {
          // access DB via jndi to get state list
          // return vector of states
       }
       // stateList is the cache object
       final Vector stateList= = getStateList();
       static {
         Hashtable ht = new Hashtable();
         ht.put("List", stateList)
       }

    }

    Here are my questions :
    1) Is it better to use HashTable or HashMap. As Hashtable is synchronized will it not cause problems.
    2) If at all the static data need to be updated, then the only way is to bring down the server is it not ?

    Thanks and regards
    sankar

  5. Your template code is the basic idea. You could use a non syncrhonized version like Hashmap as its read-only anyway.

    As for refreshing this gets touchy as were trying to prevent concurrent write access so we dont want a refresh method.

    Now, in Sybase EAServer we have the ability to "refresh" a component through a hot refresh. This would cause our ClassLoader to release its references and reload the classes, causing the cache's static intializers to fire and refresh the cache without the risk anyone is reading from that cache.

    Dave Wolf
    Internet Applications Division
    Sybase
  6. Dave,
    Sorry, still i am not convinced.
    1) In my previous sample code, why do we need to have a Hashtable ? will not the following code work ?

    Class A {
       private vector getStateList() {
          // access DB via jndi to get state list
          // return vector of states
       }
       // stateList is the public read only cache object
       public static final Vector stateList;
       static {
         stateList = getStateList();
          
       }

    }

    I have made stateList as "public" - so that it can be accessed without a Hashtable.

    2) You have mentioned that Singletons are not recommended as Application servers define their own CustomLoaders and hence there may be more than one instance of the singleton functioning. I believe this applies to the above "static final" cache object also. Please clarify.

    regards
    sangam
  7. What happens if the application is clustered. Statics are only in one JVM. One can arruge that a you dont mind having a state list in every JVM. Not very elegent but will work fine ( if no refreash allowed). What if you where to use the static to generate seqence number or where maintaining a running total.
  8. Sangam,
    Hopefully you have found a viable solution by now and would be happy to share it. I have the same issue as your account type example. Here is how I perceived solving this, but bear in mind I am an absolute rookie in the Java world.

    Define a singleton class on Webserver that uses lazy instantiation. This ensure only one instance exists and you do not have to rely on the Webserver startup to load the object. Upon instantiation, this object calls the EJB on the app server to access the defined account types - one time only.
    Now, if the account types are reconfigured, how do you update the object on the Webserver? How about use the Observer pattern to publish any changes to the account types on the app server out to the singleton on the Webserver? If for some reason there are multiple Webservers, each with their own account type object loaded, each would be synchronized.

    Barry