11 Replies Latest reply on Aug 22, 2011 2:14 AM by Sebastian Sachtleben

    Conversation injection is null

    Derk Dukker Novice

      Hi all,


      I have a ViewScoped bean where I want to inject de conversation in. In the logging I see that the conversation id is null. I use JBoss 6 but I also tested this with jboss 7. Does anybody have any ideas?





      @Stateful
      @ConversationScoped
      @Named
      public class CategoryManager {
      
          /**
           * 
           */
          private static final long serialVersionUID = 9179727796959552384L;
          
          private static final Logger log = Logger.getLogger(CategoryManager.class);
          
          @PersistenceContext(type= PersistenceContextType.EXTENDED)
          private EntityManager entityManager;
          
          private Long categoryId;
          
          @Inject
          private Conversation conversation;
          
      
          @Produces
          @Named
          public List<Category> getRootCategories() {         
      
              log.debug("entered getRootCategories");
              if(!conversation.isTransient()) {
                  conversation.begin();
                  log.debug("not transient - conversation id: " + conversation.getId());
                  System.out.println("not transient - conversation id: " + conversation.getId());
              }
              log.debug("conversation id: " + conversation.getId());
              System.out.println("conversation id: " + conversation.getId());
              
              if(getCategoryId() == null) {
                  log.debug("categoryId == null");
                  CriteriaBuilder builder = entityManager.getCriteriaBuilder();
                  CriteriaQuery<Category> cquery = builder.createQuery(Category.class);
                  Root<Category> category = cquery.from(Category.class);
                  cquery.select(category).where(builder.isNull(category.get("previousCategory")));
      
                  List<Category> rootCategories = entityManager.createQuery(cquery).getResultList();
                  
                  return rootCategories;
              }else{
                  log.debug("categoryId != null so return category with selected Id and underlying categoryList");
                  CriteriaBuilder builder = entityManager.getCriteriaBuilder();
                  CriteriaQuery<Category> cquery = builder.createQuery(Category.class);
                  Root<Category> category = cquery.from(Category.class);
                  cquery.select(category).where(builder.equal(category.get(Category_.id), categoryId));
                  List<Category> rootCategories = entityManager.createQuery(cquery).getResultList();
                  return rootCategories;
              }
              
              
              
          }
          
          @Produces
          @Named("category")
          public Category getCategory() {
              log.debug("entered getCategory");
              if(categoryId != null) {
                  log.info("categoryId: " + categoryId);
      
                  Category cat = entityManager.find(Category.class, categoryId);
                  log.info("size of categories of the selected category: " + cat.getCategories().size());
                  
                  return cat;
                 
              }else{
                  log.info("categoryId == null");
                  log.info("create new category");
                  return new Category();              
              }
          }
          
             
      
          @Produces
          @Named
          @nl.ami.marketplace.market.Category
          public Long getCategoryId() {
              log.debug("getCategoryId: " + categoryId);
              return categoryId;
          }
      
          public void setCategoryId(Long categoryId) {
              this.categoryId = categoryId;
          }
      
          
      }




        • 1. Re: Conversation injection is null
          Sebastian Sachtleben Novice

          I dont see any errors.


          Maybe you could try to remove the @Produces and @Named from all methods and access with

          #{categoryManager.methodName}


          Which weld version do use?

          • 2. Re: Conversation injection is null
            Derk Dukker Novice

            Sebastian,


            Thanks for your quick response.
            I don't think it has something to do with the @Produces and @Named. I use Weld-core-1.1.1.Final.


            Regards,


            Derk

            • 3. Re: Conversation injection is null
              Sebastian Sachtleben Novice

              Well not sure about that since I use conversation also with weld 1.1.1 Final and it works fine but without any producers.


              Maybe the produces methods have their own scope and wont use the conversation scope of the class. I would really try that.


              • 4. Re: Conversation injection is null
                Derk Dukker Novice

                As far as I know the producer methods take the scope of the class if not annotated with a scope. I will try to remove the producer methods and let you know.

                • 5. Re: Conversation injection is null
                  Sebastian Sachtleben Novice

                  I just checked my code but I have changed all conversation scoped beans to view scoped since I had problems with getting random context not active exceptions. But I'm sure conversation injection worked fine.


                  Good luck with your tests. But since no one else answers it seems to be a very specific problem here.

                  • 6. Re: Conversation injection is null
                    Derk Dukker Novice

                    Hi Sebastian,


                    I just checked the seam booking example and it's almost identical as my class. It must be some kind of configuration thing I guess... or application server issue?




                    /**
                     * @author <a href="http://community.jboss.org/people/dan.j.allen">Dan Allen</a>
                     */
                    @Stateful
                    @ConversationScoped
                    @Named
                    public class BookingAgent {
                        @Inject
                        @TypedCategory(BookingAgent.class)
                        private BookingLog log;
                    
                        @PersistenceContext(type = EXTENDED)
                        private EntityManager em;
                    
                        @Inject
                        private Instance<TemplateMessage> messageBuilder;
                    
                        @Inject
                        private Messages messages;
                    
                        @Inject
                        @Authenticated
                        private User user;
                    
                        @Inject
                        private Locale locale;
                    
                        @Inject
                        @Confirmed
                        private Event<Booking> bookingConfirmedEventSrc;
                    
                        private Hotel hotelSelection;
                    
                        private Booking booking;
                    
                        private boolean bookingValid;
                    
                        @Inject
                        private Conversation conversation;
                    
                        @Begin
                        public void selectHotel(final Long id) {
                             conversation.setTimeout(600000); //10 * 60 * 1000 (10 minutes)
                             
                            // NOTE get a fresh reference that's managed by the extended persistence context
                            hotelSelection = em.find(Hotel.class, id);
                            if (hotelSelection != null) {
                                log.hotelSelected(user != null ? user.getName() : "Anonymous", hotelSelection.getName(), hotelSelection.getCity());
                            }
                        }
                    
                        public void bookHotel() {
                            booking = new Booking(hotelSelection, user, 7, 2);
                            hotelSelection = null;
                    
                            // for demo convenience
                            booking.setCreditCardNumber("1111222233334444");
                            log.bookingInitiated(user.getName(), booking.getHotel().getName());
                    
                            messages.info(new DefaultBundleKey("booking_initiated")).defaults("You've initiated a booking at the {0}.")
                                    .params(booking.getHotel().getName());
                        }
                    
                        public void validate() {
                            log.hotelEntityInPersistenceContext(em.contains(booking.getHotel()));
                            // if we got here, all validations passed
                            bookingValid = true;
                        }
                    
                        @End
                        public void confirm() {
                            em.persist(booking);
                            bookingConfirmedEventSrc.fire(booking);
                        }
                    
                        @End
                        public void cancel() {
                            booking = null;
                            hotelSelection = null;
                        }
                    
                        public void onBookingComplete(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Confirmed final Booking booking) {
                            log.bookingConfirmed(booking.getHotel().getName(), booking.getUser().getName());
                            messages.info(new DefaultBundleKey("booking_confirmed")).defaults("You're booked to stay at the {0} {1}.")
                                    .params(booking.getHotel().getName(), new PrettyTime(locale).format(booking.getCheckinDate()));
                        }
                    
                        @Produces
                        @ConversationScoped
                        @Named
                        public Booking getBooking() {
                            return booking;
                        }
                    
                        @Produces
                        @RequestScoped
                        @Named("hotel")
                        public Hotel getSelectedHotel() {
                            return booking != null ? booking.getHotel() : hotelSelection;
                        }
                    
                        public boolean isBookingValid() {
                            return bookingValid;
                        }
                    }



                    • 7. Re: Conversation injection is null
                      Derk Dukker Novice

                      Aahhhhh stupid mistake....




                       if(!conversation.isTransient()) {
                                  conversation.begin();
                                  log.debug("not transient - conversation id: " + conversation.getId());
                                  System.out.println("not transient - conversation id: " + conversation.getId());
                              }




                      I should have removed the ! in the if statement


                      now it works!

                      • 8. Re: Conversation injection is null
                        Derk Dukker Novice

                        Next problem... when I annotate a method with @Begin




                         @Produces
                            @Named
                            @Begin
                            public List<Category> getRootCategories() {         
                        
                                log.debug("entered getRootCategories");
                        //        if(conversation.isTransient()) {
                        //            conversation.begin();
                                    log.debug("not transient - conversation id: " + conversation.getId());
                        //        }
                                log.debug("conversation id: " + conversation.getId());
                                
                                if(getCategoryId() == null) {
                                    log.debug("categoryId == null");
                                    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
                                    CriteriaQuery<Category> cquery = builder.createQuery(Category.class);
                                    Root<Category> category = cquery.from(Category.class);
                                    cquery.select(category).where(builder.isNull(category.get("previousCategory")));
                        
                                    List<Category> rootCategories = entityManager.createQuery(cquery).getResultList();
                                    
                                    return rootCategories;
                                }else{
                                    log.debug("categoryId != null so return category with selected Id and underlying categoryList");
                                    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
                                    CriteriaQuery<Category> cquery = builder.createQuery(Category.class);
                                    Root<Category> category = cquery.from(Category.class);
                                    cquery.select(category).where(builder.equal(category.get(Category_.id), categoryId));
                                    List<Category> rootCategories = entityManager.createQuery(cquery).getResultList();
                                    return rootCategories;
                                }
                        
                            }





                        I get the following exception:


                        Caused by: org.jboss.weld.exceptions.WeldException: WELD-000214 Attempt to call begin() on a long-running conversation


                        If I remove the @Begin and uncomment the if statement it works...


                        • 9. Re: Conversation injection is null
                          Sebastian Sachtleben Novice

                          Derk Dukker wrote on Aug 18, 2011 16:06:


                          Aahhhhh stupid mistake....



                           if(!conversation.isTransient()) {
                                      conversation.begin();
                                      log.debug("not transient - conversation id: " + conversation.getId());
                                      System.out.println("not transient - conversation id: " + conversation.getId());
                                  }




                          I should have removed the ! in the if statement

                          now it works!


                          Ah I thought the conversation injection is null but if you can call begin its not null :P



                          Derk Dukker wrote on Aug 18, 2011 16:54:


                          Next problem... when I annotate a method with @Begin



                           @Produces
                              @Named
                              @Begin
                              public List<Category> getRootCategories() {         
                          
                                  log.debug("entered getRootCategories");
                          //        if(conversation.isTransient()) {
                          //            conversation.begin();
                                      log.debug("not transient - conversation id: " + conversation.getId());
                          //        }
                                  log.debug("conversation id: " + conversation.getId());
                                  
                                  if(getCategoryId() == null) {
                                      log.debug("categoryId == null");
                                      CriteriaBuilder builder = entityManager.getCriteriaBuilder();
                                      CriteriaQuery<Category> cquery = builder.createQuery(Category.class);
                                      Root<Category> category = cquery.from(Category.class);
                                      cquery.select(category).where(builder.isNull(category.get("previousCategory")));
                          
                                      List<Category> rootCategories = entityManager.createQuery(cquery).getResultList();
                                      
                                      return rootCategories;
                                  }else{
                                      log.debug("categoryId != null so return category with selected Id and underlying categoryList");
                                      CriteriaBuilder builder = entityManager.getCriteriaBuilder();
                                      CriteriaQuery<Category> cquery = builder.createQuery(Category.class);
                                      Root<Category> category = cquery.from(Category.class);
                                      cquery.select(category).where(builder.equal(category.get(Category_.id), categoryId));
                                      List<Category> rootCategories = entityManager.createQuery(cquery).getResultList();
                                      return rootCategories;
                                  }
                          
                              }





                          I get the following exception:

                          Caused by: org.jboss.weld.exceptions.WeldException: WELD-000214 Attempt to call begin() on a long-running conversation

                          If I remove the @Begin and uncomment the if statement it works...




                          That is currently the way togo with check if transient and create then. Dont use @Begin!

                          • 10. Re: Conversation injection is null
                            Derk Dukker Novice

                            Sebastian Sachtleben wrote on Aug 19, 2011 03:55:



                            Derk Dukker wrote on Aug 18, 2011 16:06:


                            Aahhhhh stupid mistake....



                             if(!conversation.isTransient()) {
                                        conversation.begin();
                                        log.debug("not transient - conversation id: " + conversation.getId());
                                        System.out.println("not transient - conversation id: " + conversation.getId());
                                    }




                            I should have removed the ! in the if statement

                            now it works!


                            Ah I thought the conversation injection is null but if you can call begin its not null :P


                            Derk Dukker wrote on Aug 18, 2011 16:54:


                            Next problem... when I annotate a method with @Begin



                             @Produces
                                @Named
                                @Begin
                                public List<Category> getRootCategories() {         
                            
                                    log.debug("entered getRootCategories");
                            //        if(conversation.isTransient()) {
                            //            conversation.begin();
                                        log.debug("not transient - conversation id: " + conversation.getId());
                            //        }
                                    log.debug("conversation id: " + conversation.getId());
                                    
                                    if(getCategoryId() == null) {
                                        log.debug("categoryId == null");
                                        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
                                        CriteriaQuery<Category> cquery = builder.createQuery(Category.class);
                                        Root<Category> category = cquery.from(Category.class);
                                        cquery.select(category).where(builder.isNull(category.get("previousCategory")));
                            
                                        List<Category> rootCategories = entityManager.createQuery(cquery).getResultList();
                                        
                                        return rootCategories;
                                    }else{
                                        log.debug("categoryId != null so return category with selected Id and underlying categoryList");
                                        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
                                        CriteriaQuery<Category> cquery = builder.createQuery(Category.class);
                                        Root<Category> category = cquery.from(Category.class);
                                        cquery.select(category).where(builder.equal(category.get(Category_.id), categoryId));
                                        List<Category> rootCategories = entityManager.createQuery(cquery).getResultList();
                                        return rootCategories;
                                    }
                            
                                }





                            I get the following exception:

                            Caused by: org.jboss.weld.exceptions.WeldException: WELD-000214 Attempt to call begin() on a long-running conversation

                            If I remove the @Begin and uncomment the if statement it works...




                            That is currently the way togo with check if transient and create then. Dont use @Begin!


                            With Seam2 you have


                            @Begin(join=true)



                            how is this solved in Weld? Or is this not yet implemented?

                            • 11. Re: Conversation injection is null
                              Sebastian Sachtleben Novice

                              Not sure but I saw in a jira issue that


                              if(!conversation.isTransient()) {
                                 conversation.begin();
                              }



                              is the proper way for conversation start currently.