7 Replies Latest reply on Jul 9, 2007 5:03 PM by bkroeger

    best way of using application scope constants?

    ellenzhao

      In my application there are a lot of application scope values (read most, very seldom update/insert/delete), things like all Zip Codes in a country, names of all agents, etc. They resides in various different tables in the database. I want to _always_ cache them in the memory, once and for all, so that other stateful beans can use these values without creating new instances of these data wrapper class. For example,

      @Stateful
      @Name("fooAction")
      @Scope(CONVERSATION)
      public class FooAction implements Serializable, Foo{
      
       //here i want to load the in-memory data like all zipcodes....
       private SomeBean applicationScopeValues;
       .....
      
      }
      
      


      What is the best way?

      If I use bijection, I would need to create a stateful bean (or stateless, if the data is 100% read-only), annotate the application scope, and then in this bean, do things like:

      
      @Stateful
      @Scope(APPLICATION)
      @Name("dataStore")
      public class DataStoreImpl implements Serializable, DataStore{
      
       //how do I get reference of this list from other action beans if I use
       // use the @Out here?
       private List<Zipcode> allZipcodes;
      
       @Create
       public void findAllZipcodes(){
       String query ="select z from Zipcode z";
       this.allZipcodes = entityManager.createQuery(query).getResultList();
       }
      
       //getters and setters
      }
      
      


      Then in the FooAction class, I would need to do:
      @In(create=true) private DataStore dataStore;
      


      Am I doing right this way? Can I avoid creating multiple instances of the DataStore this way?

      Any better options? Thanks very much in advance!!


      Regards,
      Ellen

        • 1. Re: best way of using application scope constants?
          gavin.king

          Yes, thats reasonable, except that you should not use a SFSB, since your APPLICATION scoped object must be multithreaded.

          • 2. Re: best way of using application scope constants?
            ellenzhao

            What's the consequence of using SFSB here? Performance/Scalability hit? Thanks!


            Regards,
            Ellen

            • 3. Re: best way of using application scope constants?
              gavin.king

              SFSBs throw exceptions if accessed concurrently by multiple threads. (Unless you add an @Synchronized annotation, which will affect scalability.)

              • 4. Re: best way of using application scope constants?
                bkroeger

                Hi, I would like to know if Ellen got this working, I have tried to do the same thing but when I attempt to get a reference to the EntityManager in my application scope bean:

                @PersistenceContext
                 private EntityManager em;
                

                I get an error message telling me my bean needs to be in session scope, which defeats the purpose as I will end up re-creating my list every time a new session starts.

                What's the best way to have an application scope (static) list available to the application, that requires use of the EntityManager?

                • 5. Re: best way of using application scope constants?
                  jazir1979

                  I'm doing a similar thing to this using a SLSB with application scoped @Factory methods. It works well.

                  @Stateless
                  @Name("factory")
                  public class FactoryActionBean extends BaseActionBean implements FactoryAction {
                   @In(create = true, value = "entityManager")
                   protected EntityManager em;
                  
                   /** {@inheritDoc} */
                   @Factory(value = "statusList", scope = ScopeType.APPLICATION)
                   public List<Status> getStatuses() {
                   return service.findReservationStatuses(em);
                   }
                  


                  Watch out though, using the above list with <s:convertEntity/> broke in Seam 2 Beta 1 due to JBSEAM-1487, but this is now fixed in CVS, thanks to Pete.

                  "bkroeger" wrote:
                  Hi, I would like to know if Ellen got this working, I have tried to do the same thing but when I attempt to get a reference to the EntityManager in my application scope bean:
                  @PersistenceContext
                   private EntityManager em;
                  

                  I get an error message telling me my bean needs to be in session scope, which defeats the purpose as I will end up re-creating my list every time a new session starts.

                  What's the best way to have an application scope (static) list available to the application, that requires use of the EntityManager?


                  • 6. Re: best way of using application scope constants?
                    ellenzhao

                    Hi bkroeger,

                    I am now having exactly the same problem like yours (got "failed to lazily initialize ...." since the entities in the list have their own collections and their collections would be implicitely modified in other stateful beans in my application, not from this dataStore bean...I got rid of this exception with a Foo foo2 = entityManager.merge(foo), but it's so incredibly costly because there are over 7000 foos in the list....) I'll try out jazir1979's recommendation soon. Have you got your code work in a reasonably performant way? Please let me know! Thanks!


                    Regards,
                    Ellen

                    • 7. Re: best way of using application scope constants?
                      bkroeger

                      Here's another way to do it that feels like a workaround. The application scope bean is injected into a stateful session bean that is able to initialize the application bean's static list through the use of the EntityManager. You annotate the stateful session bean method initializing the list with @Create and when the stateful session bean is instantiated, this method checks a boolean in the application scope bean to see if the list already exists, if it doesn't you create the list.