1 2 Previous Next 18 Replies Latest reply on Apr 25, 2007 2:06 AM by baz

    Initialization code

    sammy8306

      Well, my first steps with seam are succesful. However, I'm wondering how I should add code that should only run (once) at the initialization of the web-app. My first idea was to create an application scoped component, auto-create set to true and to put the code in the constructor. However, there are 2 problems: this component is only instantiated when I inject it somewhere (makes sense, lazy instantiation). Furthermore, I need access to the Seam managed EntityManager. I tried to inject it into the application component, however injected values are not available in the constructor, it seems (which makes sense as well).

        • 1. Re: Initialization code
          pmuir

          Create an Application scoped component annotated with @Startup and with a @Create method

          • 2. Re: Initialization code
            sammy8306

            Thanks! One problem though

            @Startup
            public class PopulateDB
            {
             @In
             private EntityManager em;
            
             @Create
             public void populateDB(){
             em.beginTransaction();
             CreateTestData.createData(em);
             }
            }
            


            Leads to this exception: javax.persistence.TransactionRequiredException: no transaction is in progress

            I can't start a transaction from the EntityManager either: using getTransaction().begin() gives this exception: java.lang.IllegalStateException: JTA EntityManager cannot access a transactions

            And yes, I am aware of the import.sql mechanism, however doing it programmatically would help me tremendously in my setting. Any ideas?

            • 3. Re: Initialization code
              sammy8306

              Oops, the em.beginTransaction() should not be there in the code block above (why can't I edit my posts?)

              • 4. Re: Initialization code
                sammy8306

                Bumping this one since I'd really like to make this work... thanks!

                • 5. Re: Initialization code
                  pmuir

                  You can't/shouldn't access an EntityManager during @Startup.

                  My suggestion is to schedule your method to execute at a later date using @Asynchronous

                  • 6. Re: Initialization code
                    denis.diggin

                    Try @Startup(depends="org.jboss.seam.core.ejb")

                    • 7. Re: Initialization code
                      sammy8306

                      That looked promising, but same problem unfortunately... hm, anything else it could depend upon? Or should I just heed petemuir's advice ;-) ?

                      • 8. Re: Initialization code

                        You might be able to use an observer on a seam contextual event. Unfortunately I don't see a "seam fully initialized event". Maybe postCreate, or if your app requires authentication, preAuthenticate. I'm just looking at the docs, there may be additional events that have been added. It shouldn't be hard to add that "fully initialized event" so other components can kick off startup tasks without worrying about what resources are available and what aren't.

                        • 9. Re: Initialization code
                          pmuir

                          org.jboss.seam.core.ejb is the EJB microcontainer - nothing to do with the entitymanager.

                          I've added an org.jboss.seam.postInitialization event to CVS, consider this an experimental feature for now that may be removed.

                          • 10. Re: Initialization code
                            sammy8306

                            I solved my problem, kind of obvious now I know Seam a bit better:

                            1) created an application scope component that does the DB initialization in an @Create component (do not use @Startup for this component)
                            2) Inject this into the first component (using @In(create=true) that gets called in the application - the application scope ensures that the component only is created once... right?

                            Looks like its working anyway. Thanks all!

                            • 11. Re: Initialization code
                              sammy8306

                              of course this doesn't work well when the entry point of the application is not a single well-defined point, so I think I will look at the eventlistener solution as well.

                              • 12. Re: Initialization code
                                pmuir

                                Yes this works, but it's not the neatest :(

                                • 13. Re: Initialization code
                                  pmuir

                                  I need to get Gavin to review that change to check he is happy with it hence the note about it being experimental. I'll post back here if it's not ok.

                                  • 14. Re: Initialization code

                                    Hmm, PMs don't seem to be activated. Anyway, please take a look at the placing of the Events.instance().raiseEvent("org.jboss.seam.postInitialization"); line. I'm guessing that this should come at the end of the method, or at least after the Lifecycle.endInitialization(); since endInitialization resets all the contexts.

                                    After the "done initializing seam" logging seems appropriate since once the event is raised Seam will synchronously execute any observers which may have logging of their own. All of this should happen after seam has finish initializing.

                                    Sry for the forum post. Didn't know of a better way to send this.

                                    1 2 Previous Next