Singleton for access to very large instances


EJB design: Singleton for access to very large instances

  1. I have the following design issue. I am developing an electronic health record application. I need to maintain large amount of information for each patient and there will be lots of patients (health issues, investigation results, basically anything a doctor may request). My application will be accessed by web services so I should make a stateless session bean that exposes some services. I was told to read from the database at startup, populate my objects and make my queries on these objects NOT on the database. How can I maintain only a single copy of my objects accessible by more than one instance of my stateless session bean? In earlier projects I used Singleton but I understand that it is harder to use in EJB. Also is there such a performance penalty for accessing the database at each query that I need to keep it all in the memory? I am also thinking of a mixed solution , implementing a Stateful framework of some kind because a doctor will likely access information regarding only one patient in a session. I can then retrieve the information for that patient from the database and store it as long as the stateful session bean is in conversational state. Thank you, any response will be welcome.
  2. To me this sounds like a classic premature optimization.:). Databases are fairly stable these days (ofcourse they need tuning as well). 1. What would be size of the tables and how complex are they. Probably 20 million records or 100 million records?. You can tweak your query and partition your tables based on the dates and other informations. 2. I would go with simple and understandable design initially and only when you figure out that the database queries are becoming extremely expensive, you would need to look at it and cache it instead of quering DB. ~Rajesh.B
  3. You need to make a cache of the data because very likely underlying there are many different syn and asyn data sources. But I won't implement the cache in objects, if that is your case, due to performance. Stateful beans are justified to be used only when a "session" is mandated. What users of EHR/EMR want most of the time are read operations. Very likely the sessions, if you do use stateful beans, will be idle for long time between simply because that is how users use those systems. From what you said, I will make read operations on read-only objects, and write operations on DAO or via JDBC to DB, then populate the objects.
  4. The beans will be stateless. The problem is how do I hold reference to the cached objects in the stateless beans. I understand that you can keep non-conversational information in private variables but it is not guaranteed that the data is not lost.
  5. 1. Implement caching as a singleton object 2. Use factory pattern to get the cache manager instance 3. store and retrieve data from cache. From your stateless session bean methods (in all methods where you want to retrieve data from cache), always obtain the reference of the cache manager instance and use the get methods to retrieve data from cache. For eg. (a ssb method) public void dosomething(.some input..) { CacheManager cm = InstanceFactory.getCacheManagerInstance(); CacheKey key = your key, based on input etc.. SomeData sd = (SomeData) cm.get(key); .... } --------------------- interface CacheManager { public void put(CacheKey key, Object value); public Object get(CacheKey key); public void invalidate(CacheKey key); .. .. } --------------------- Alternatively, you can use any of the existing caching framework if it is suitable for your need, just wrap it with your classes and use your apis in your classes, not the third party api directly.
  6. I agree with :
    Premature optimizations could be an evil
    Posted by: Rajesh Balamohan on March 22, 2008 in response to Message #249385 databases are best used for this purpose. If there is contention with the database usage, a replicate database of a full extract (Or Dump and load) of a database should be considered. Replicate if you can ensure data letency, which you would have if you loaded the objects into any Caching mechanism. This statement:
    "I was told to read from the database at startup, populate my objects and make my queries on these objects NOT on the database. "
    dictates your solution, I have two suggestions. First, Space-based architecture (SBA) is a design pattern that leverages the tuple space paragidm for achieving linear scalability of stateful, high-performance applications. Look into Java Spaces implementation such as Gigaspaces, which allows you to pre-load the caches of objects from a database for query purposes, and scales and is very fast. Coherenece if you are an Oracle shop and have Oracle representation (Not exactly a Java Spaces Implementation, but uses the same ) Secondly, Look at a replication of an extract based system to extract data from the main database to a Decision Support database, that your application can query as needed. So you can use the Tools of the Trade, JDBC, JPA, EJB in native functionality without the restriction of not using the main database. best of of luck. Sometime you have to play with the hand you are dealt with. Tony McClay Sun Certified Enterprise Architect JEE 5 (SCEA CS-310-052) Sun Certified Business Components Developer JEE5 (SCBCD CX-310-091) Sun Certified Web Components Developer (SCWCD CX-310-081) Sun Certified Java Programmer 5 (SCJP CX-310-056)
  7. If the database is very large, it would be doubtfull to cache the whole. Even if it can cache now, the system would also grow continuosly. I would prefer to database optimization usage and partial caching. database optimization might be opening large connection pool, increasing connection timeout, optimized sql query/ PL/SQL usage. partial caching, depending on the nature itself. cache paging would help a lot(eg: just cache what being retrieved/frequency up to the max size) follow Least Recently Used, Least Frequently Used or combination of them.
  8. May be you can try the memory mapped usage of dataobjects for the data retrieved from database