5 Replies Latest reply on Aug 4, 2010 12:50 PM by pmuir

    JSF transactions closing JCA resource during page render

    cory_prowse

      Hi,


      I am using a Producer Method to create a Session from a JCA resource that will then of course close with the transaction.


      Problem is, after the first use of the Session in a JSF page it gets closed, causing future calls to fail due to Inactive logical session handle called.


      Is there a way to achieve this cleanly with WELD?


      Here is my Producer:


      public class JcrSessionProducer {
      
          private static final char[] EMPTY_PASSWORD = "".toCharArray();
      
          @Resource(name = "jcr/repository", type = javax.jcr.Repository.class)
          private Repository repository;
      
          @Default
          @Inject
          private Principal principal;
      
          @Produces
          @RequestScoped
          public Session loginCurrentCallerPrinciper() throws LoginException, RepositoryException {
              return repository.login(new SimpleCredentials(principal.getName(), EMPTY_PASSWORD));
          }
      
          // This is not required when using a JCA
          // public void logoutSession(@Disposes final Session session) {
          // session.logout();
          // }
      
      }
      



      and here is a simplified version of the EJB which is called from JSF:


      @Stateless
      @Named
      public class Jcr {
      
          @Inject
          private Session session;
      
          public List<NodeWrapper> feed(final String absPath) throws RepositoryException {
              try {
                  return nodeIteratorToStringList(session.getNode(absPath).getNodes("item*"));
              } catch (final PathNotFoundException e) {
                  return null;
              }
          }
      }
      



      and a snippet of my JSF:


      <ui:repeat value="#{jcr.feed('/blog')}" var="node">
           <h:outputText value="Content: #{node.content}" />
      </ui:repeat>
      <ui:repeat value="#{jcr.feed('/blog/feed1')}" var="node">
           <h:outputText value="Content: #{node.content}" />
      </ui:repeat>
      



      The error occurs on the second call to jcr.feed().


      I've tried various things (Scopes, TransactionAttributes) but I thought the code above should work?


      -- Cory

        • 1. Re: JSF transactions closing JCA resource during page render
          swd847

          Make JcrSessionProducer request scoped.


          All injected resources have scope @Dependent, which ties them to the life-cycle of the object they are injected into. In this case JcrSessionProducer is also @Dependent, so it will be destroyed and the Resource closed after the first EL evaluation.

          • 2. Re: JSF transactions closing JCA resource during page render
            cory_prowse

            Stuart Douglas wrote on Aug 02, 2010 00:23:


            Make JcrSessionProducer request scoped.


            Alas no change.


            It seems that after the first EL evaluation the distributed transaction is committed, causing the JCA Managed Connection handle to be closed (I've stepped through the code).
            So next EL evaluation will fail due to a closed handle.


            It seems that either I need the transaction to bracket the entire JSF page, or for there to be a @TransactionScoped option (I know there isn't one).


            I'd really like to get this Producer Method working for all the obvious reasons.

            • 3. Re: JSF transactions closing JCA resource during page render
              swd847

              Actually there is one, seam-persistence contains @TransactionScoped, but you will have to build it yourself because it has not had a released yet. You will also probably need to build weld-extensions from source, because seam-persistence relies on weldx features that were not in the last release.


              What you really need is probably seam managed transactions, to open a transaction for you in the render response phase. This should be implemented in the next few weeks.


              Another short term solution could be removing the @RequestScoped annotation on the producer method, and have it Dependent scoped.

              • 4. Re: JSF transactions closing JCA resource during page render
                cory_prowse

                Stuart Douglas wrote on Aug 02, 2010 01:37:

                Actually there is one, seam-persistence contains @TransactionScoped, but you will have to build it yourself because it has not had a released yet. You will also probably need to build weld-extensions from source, because seam-persistence relies on weldx features that were not in the last release.



                What you really need is probably seam managed transactions, to open a transaction for you in the render response phase. This should be implemented in the next few weeks.



                Another short term solution could be removing the @RequestScoped annotation on the producer method, and have it Dependent scoped.



                Firstly, thank you for the responses thus far, appreciate it.


                I'm tempted to try out the new features, but I'll hold off on trying out pre-release code for now - I'm able to get this working with some ugly code that I'd really prefer WELD to take care of.


                I've tried removing the @RequestScoped from the Producer but the XATransaction is still committed after each JSF EL evaluation.


                I feel like I'm missing some key concept here with transactions and JSF page rendering, however there doesn't appear to be anything in the JSF 2.0 spec about transactions at all.

                • 5. Re: JSF transactions closing JCA resource during page render
                  pmuir

                  As Stuart implies, this is something that is missing from Java EE, and so something we have to provide in Seam 3. We're still working on getting the full Seam environment available for EE6.