8 Replies Latest reply on Jan 12, 2018 11:15 AM by bookwood

    TransactionRequiredException with the jpa idm quick start

    fer.marino

      It seemed right to me open a new discussion for my own problem rather than abusing of the other one so here we are.

      I'm running the demo in the subject on jboss as 7.1 + richfaces. Basically I did not made any major modifications, I'm still using the H2 database provided by the server, but not in memory. I'm also having hibernate.hbm2ddl.auto set to validate, to not delete and recreate the db every time. I've used the startup script just once to create the db, and then deleted.

      All seems to works fine, so I've started to implements some view for the CRUD operations on the basic idm model provided. Here some code:

       

      @SessionScoped
      @ManagedBean
      public class UserManager {
          @Inject
          private PartitionManager partitionManager;
      
      ....
      
      public void saveUser() {
        IdentityManager im = partitionManager.createIdentityManager();
        im.update(editUser);
        if(password != null && !password.isEmpty() && confirmPassword != null && !confirmPassword.isEmpty())
           if(password.equals(confirmPassword))
              im.updateCredential(editUser, new Password(password));
           else
              FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Password must match"));
        log.log(Level.INFO, "User "+editUser.getLoginName()+ " updated succesfully");
      }
      

       

      The im.update fail:

      PLIDM000604: Could not update AttributedType

      Caused by: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)

       

      I'm investigating this problem for two days. The entitymanager is correctly created and provided by the producer method, and with that it let me authenticate successfully. The em injected by the context is an instance of TransactionScopedEntityManager, so it should be fine. Calling em.getTransaction() fail with this java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction(), and this is also should be correct (getTransaction is used only for resource local data sources, isn't it?)


      What I'm I doing wrong? In the startup script all seems to be working fine, why here it does not??


      In the documentation it is said that IdentityManager is a requested scoped bean, while the partition manager is application scoped. Assuming that this scope is the same as jsf managed beans, I've injected the partition manager in my sessionscoped bean, but I've seen that injecting directly the identity manager works. I'm not grasping something here...

        • 1. Re: TransactionRequiredException with the jpa idm quick start
          shane.bryzak

          Could you please post the full class code for your EntityManager producer method?

          • 2. Re: Re: TransactionRequiredException with the jpa idm quick start
            fer.marino
            @ApplicationScoped
            public class Resources {
                @Produces
                public Logger produceLog(InjectionPoint injectionPoint) {
                    return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
                }
            
            
                @Produces
                @RequestScoped
                public FacesContext produceFacesContext() {
                    return FacesContext.getCurrentInstance();
                }
               
                @PersistenceContext(unitName = "picketlink-default")
                @Produces
                @PicketLink
                private EntityManager em;
            
            
                /*
                 * Since we are using JPAIdentityStore to store identity-related data, we must provide it with an EntityManager via a
                 * producer method or field annotated with the @PicketLink qualifier.
                 */
               
                public EntityManager getPicketLinkEntityManager() {
                    return em;
                }
            
            }
            
            
            
            
            
            

             

            Right now I'm wondering about that applicationScoped annotation

             

             

            edit: switched back to stateful, and I got this during application deployment:

            JBAS014101: Failed to find SFSB instance with session ID [....]

             

            I got also two more strange message during deployment:

             

            08:40:42,532 WARN  [org.hibernate.dialect.H2Dialect] (MSC service thread 1-5) HHH000431: Unable to determine H2 database version, certain features may not work

            08:40:42,536 INFO  [org.hibernate.engine.jdbc.internal.LobCreatorBuilder] (MSC service thread 1-5) HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4

             

            As I said, I do not provide my own jar for H2 but I use the one provided by jboss as. Actually there isn't even a reference in them pom.xml about h2.

            • 3. Re: Re: TransactionRequiredException with the jpa idm quick start
              shane.bryzak

              Those messages look harmless.  Was the "Failed to find SFSB..." message an exception?  Did your application work when you used a @Stateful producer bean?

              • 4. Re: Re: TransactionRequiredException with the jpa idm quick start
                fer.marino

                this is the full line:

                12:36:50,553 INFO  [org.jboss.as.ejb3] (MSC service thread 1-11) JBAS014101: Failed to find SFSB instance with session ID {[-36, -2, 17, -19, -100, 112, 68, -108, -117, -123, 57, 17, -102, 116, -50, -15]} in cache

                it appears every time I deploy the application.

                 

                Anyway no, I got the same error even with the stateful annotation: Could not update AttributeType due to TransactionRequiredException

                 

                 

                Thank you for your patient Shane!

                • 5. Re: Re: TransactionRequiredException with the jpa idm quick start
                  shane.bryzak

                  That message looks fine to me.  I'm at a loss what to suggest next - if you would like to create a minimal, buildable project that reproduces the issue I would be happy to look into it deeper.  You can attach the project to a JIRA issue (issues.jboss.org) and assign to me.

                  • 6. Re: TransactionRequiredException with the jpa idm quick start
                    fer.marino

                    we can continue here

                     

                    here the sample project:

                    https://www.dropbox.com/s/55kit14al3l2fja/ssra-EE.zip

                     

                    It's an eclipse project created with the EE version and jboss tools. Also you need to copy the db file into your home dir.

                     

                    Just login with john/demo, then click on the user icon in the toolbar. A form will appear, just click save and that will trigger a method of a managed bean that will try to persist any modification made to the user. I'm running this project in jboss as 7.1.1

                    • 7. Re: TransactionRequiredException with the jpa idm quick start
                      fer.marino

                      ok now, this works:

                      @Stateless
                      @Named
                      public class TestPicketlink {
                        @Inject
                        private IdentityManager im;
                      
                        @Inject 
                        Logger log;
                      
                        public TestPicketlink() {}
                      
                        public void save(User u, String userPassword) {
                           if(u.getId() == null || u.getId().isEmpty()) { // new user
                               User john = new User("johnny");
                               john.setEmail("john@acme.com");
                               john.setFirstName("John");
                               john.setLastName("Smith");
                               im.add(john);
                               im.updateCredential(john, new Password("demo"));
                      
                      
                               log.log(Level.INFO, "User "+u.getFirstName()+" "+u.getLastName()+" added.");
                           } else { // edit user
                               im.update(u);
                               if(userPassword != null && !userPassword.isEmpty())
                                  im.updateCredential(u, new Password(userPassword));
                      
                      
                               log.log(Level.INFO, "User "+u.getFirstName()+" "+u.getLastName()+" updated.");
                           }
                        }
                      
                      
                      
                      }
                      

                      this does not:

                      @ManagedBean
                      @SessionScoped
                      public class TestPicketlink {
                        @Inject
                        private IdentityManager im;
                      
                        @Inject 
                        Logger log;
                      
                        public TestPicketlink() {}
                      
                        public void save(User u, String userPassword) {
                            if(u.getId() == null || u.getId().isEmpty()) { // new user
                               User john = new User("johnny");
                               john.setEmail("john@acme.com");
                               john.setFirstName("John");
                               john.setLastName("Smith");
                               im.add(john);
                               im.updateCredential(john, new Password("demo"));
                      
                      
                               log.log(Level.INFO, "User "+u.getFirstName()+" "+u.getLastName()+" added.");
                        } else { // edit user
                                im.update(u);
                        if(userPassword != null && !userPassword.isEmpty())
                        im.updateCredential(u, new Password(userPassword));
                      
                      
                        log.log(Level.INFO, "User "+u.getFirstName()+" "+u.getLastName()+" updated.");
                        }
                        }
                      }
                      

                       

                      god knows why. It took me a week and I still don't know why. Going to get drunk now, feel free to join me.

                      • 8. Re: TransactionRequiredException with the jpa idm quick start
                        bookwood

                        I have the same Problem. The main difference is, the working bean is @Stateless annotated and the not working bean @Sessionscoped. I think this is the problem. I think it would be a solution to put all load, save and update operations into a new bean, Stateless annotated.