9 Replies Latest reply on Jun 8, 2011 6:33 AM by vidda

    Persistence Context per Conversation - possible ?

      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 ?
          blabno

          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 ?

            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 ?

              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 ?
                blabno

                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 ?

                  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 ?
                    blabno

                    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());

                    • 7. Re: Persistence Context per Conversation - possible ?

                      Great, thanks for your help :)

                      • 8. Re: Persistence Context per Conversation - possible ?

                        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 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);