6 Replies Latest reply on Feb 20, 2009 10:06 PM by ztiringer

    EntityManager closed in Application scoped EntityQuery component

    ztiringer

      I have an application scoped EntityQuery component that gets registered with Quartz after startup to do some regular DB scan (and un/register some other components with Quartz). The first time this component executes OK (I can see the logs), but all subsequent invocations fail with IllegalStateException: EntityManager closed. I have auto-create true at managed persistence context in components.xml


      I tried setting entityManager to null at the end of the constructor logic, to force getting a new entityManager, the same with @PrePassivate - no success. I tried even @In (create=true) to inject entityManager (though EntityQuery doesn't need this).


      When registering a Conversation scoped component with Quartz, it works just fine.


      What am I doing wrong? How do I workaround this? Is this expected behavior or a bug?

        • 1. Re: EntityManager closed in Application scoped EntityQuery component
          swd847

          EntityQueries are not really designed to be put in the application scope. If no parameters have changed they will keep returning the same list of entities, which will be detached as soon as the creating conversation has ended (and will be a thread safety issue before that).


          Async tasks are generally better off using a transaction scoped entityManager. Just issue the query directly in whatever component is doing the scan and it will cause far less problems.


          Setting the entityManager to null will not do anything. The seam injection logic happens after the constructor call, and after a method invocation all injected fields are set to null to prevent resource leaks.


          • 2. Re: EntityManager closed in Application scoped EntityQuery component
            ztiringer

            Hi Stuart,


            Thanks for your quick reply. In my case the same query might return a different list of entities, as other applications access the same DB and might add new records or modify existing ones.


            Actually, I did start out with just injecting the entityManager (no EntityQuery), but it resulted in a NPE (I use an Observer on postInitialization to kick off after startup, and put create=true on the injection - and still), that's why I looked for other ways to resolve the issue and found that with EntityQuery it does connect to the DB.


            After your reply, I went back to investigate more the injection of the entityManager (and this time with more frequent Quartz invocations) and I realized that even though the first call to the em results in NPE, the subsequent calls succeed.


            So now I have plain em injection that fails the first time and works later, and EntityQuery that works correctly only the first time. Can someone please advise to find a solution that works all the time?

            • 3. Re: EntityManager closed in Application scoped EntityQuery component
              swd847

              Post your code.

              • 4. Re: EntityManager closed in Application scoped EntityQuery component
                fridgebuzz

                I may be speaking completely out of turn here, but... I had a sort of similar problem with an application scoped component using a Quartz Timer and having trouble with the EntityManager.


                I posted about it and received the answer I needed. Perhaps there is something in this thread that will aid you.


                For what it's worth: The thread...


                Cheers,


                Vanessa

                • 5. Re: EntityManager closed in Application scoped EntityQuery component
                  israeldl
                  Use a stateless scoped component with a entityManager.

                  Example

                  @Name("blaBla)
                  @Scope(APPLICATION)
                  public class myApplicationComp{
                       @In(create = true)
                       private EntityManagerDAO myEn;
                  }


                  @Name("myEn")
                  @Scope(STATELESS)
                  public class EntityManagerDAO{
                       @In(create = true)
                       private EntityManager em;
                  }



                  Maybe it's works.
                  • 6. Re: EntityManager closed in Application scoped EntityQuery component
                    ztiringer

                    Thanks for your help. I figured it out in the meantime. I was making the first call to the DB from the constructor (so no em injection took place), that's why it was failing. Thanks again.