9 Replies Latest reply on Jun 8, 2011 6:33 AM by David Herrera Alonso

    Persistence Context per Conversation - possible ?

    first last Newbie

      Hi,


      I heavily use nested conversation in my app, in order to allow the user both to have a workspace that is composed of different concurrent conversations, and also in order to utilize the breadcrumbs mechanism.


      I just recently found out that when I flush a nested-conversation's entityManager (I'm using flushMode=manual) - All its parent conversations are flushed as well (!!)


      Is there a way for each conversation to have its own independent entityManager or Persistence context?? I'm referring to nested hierarchies of course.


      (btw I'm using EntityHome and EntityQuery, if it's of any relevance)


      Thanks for any info.

        • 1. Re: Persistence Context per Conversation - possible ?
          Bernard Labno Master

          This is long requested feature. Check JIRA. I do not think it will be solved in next year or two.

          • 2. Re: Persistence Context per Conversation - possible ?
            first last Newbie

            So I see, thanks for replying,


            Is there a work-around ?
            Something like having our own EntityManager field in all relevant classes, and overriding EntityHome.getEntityManager() to provide it instead of the default one ?


            Or maybe the problem is that we can't even set this field to point to our own designated and seperate Entity Manager ?

            • 3. Re: Persistence Context per Conversation - possible ?
              first last Newbie

              As I see here, looks like this could indeed be solved by having a separate Entity Manager for the parent conversation, and the child one.


              BUT - in the given link a seperate Entity Manager is defined via components.xml :




              <persistence:managed-persistence-context name="entityManager2"
                                                   auto-create="true"
                                    persistence-unit-jndi-name="java:/someEntityManagerFactory"/> 



              and then for the Home class at hand (which is at work in the child conversation) we have :




              @Override
                  protected String getPersistenceContextName()
                  {
                     return "entityManager2";
                  } 



              Thing is - in my implementation I got lots of nested conversations, and each requires a separate Entity Manager. How can we programaticaly supply a new separate Entity Manager ??

              • 4. Re: Persistence Context per Conversation - possible ?
                Bernard Labno Master

                To create entityManager programatically use entityManagerFactory. In my opinion it would be best to intercept org.jboss.seam.core.Manager.beginNestedConversation method and put new entityManager into new conversation's scope after it is invoked.

                • 5. Re: Persistence Context per Conversation - possible ?
                  first last Newbie

                  man, thanks for answering, I'm really in a tight corner here (lack of time).


                  That sounds great, can ya tell me how do I put new entityManager into new conversation's scope ?


                  Meaning :


                  How do I get a new entityManager (which is a fresh and separate from the parent's one - the link I gave said to declare one statically in components.xml - I want an unlimited number of new entity managers).


                  How do I put it into the conversation ?


                  Thanks again !

                  • 6. Re: Persistence Context per Conversation - possible ?
                    Bernard Labno Master

                    components.xml:


                    <persistence:managed-persistence-context name="entityManager"
                                                                 auto-create="true"
                                                                 entity-manager-factory="#{yourEntityManagerFactory}"/>
                    
                    <persistence:entity-manager-factory name="yourEntityManagerFactory"
                                                            persistence-unit-name="yourPersistenceUnit"/>



                    Some action:


                    EntityManagerFactory emf = (EntityManagerFactory) Component.getInstance("yourEntityManagerFactory");
                    Contexts.getConversationContext().set("entityManager",emf.createEntityManager());

                    • 8. Re: Persistence Context per Conversation - possible ?
                      David Herrera Alonso Newbie

                      Using this method to create and outject a new EntityManager on a conversation, I get ClassCastException when setting new EntityManager:




                      java.lang.ClassCastException: org.hibernate.ejb.EntityManagerImpl cannot be cast to org.jboss.seam.persistence.PersistenceContextManager







                      Any idea of what can I do to solve this? Thanks :)

                      • 9. Re: Persistence Context per Conversation - possible ?
                        David Herrera Alonso Newbie

                        David Herrera Alonso wrote on Jun 07, 2011 07:01:

                        Any idea of what can I do to solve this? Thanks :)


                        Solved :). I have create it by hand a ManagedPersistenceContext and now it works and I have a new and diferente EntityManager on nested conversation.



                        ManagedPersistenceContext parentEntityManager = (ManagedPersistenceContext) Contexts.getConversationContext().get("entityManager");
                        
                                        ManagedPersistenceContext nestedEntityManager = new ManagedPersistenceContext();
                                        nestedEntityManager.create(new Component(ManagedPersistenceContext.class, "entityManager"));
                                        nestedEntityManager.setEntityManagerFactory(parentEntityManager.getEntityManagerFactory());
                                        nestedEntityManager.setFilters(parentEntityManager.getFilters());
                                        nestedEntityManager.setPersistenceUnitJndiName(parentEntityManager.getPersistenceUnitJndiName());
                        
                                        Contexts.getConversationContext().set("entityManager", nestedEntityManager);