1 Reply Latest reply on Jul 8, 2012 12:51 PM by smoking81

    questions about Jboss quickstarts

    smoking81 Newbie

      Hello everybody,

       

      I am playing around with Jboss quickstarts and I found a couple of interesting points I cannot really understand...

       

      1) First, why is MemberListProducer in kitchensink not an EJB? What about transaction management? I thought that only EJB methods had integrated transaction demarcation:

       

      package org.jboss.as.quickstarts.kitchensink.data;
      
      import org.jboss.as.quickstarts.kitchensink.model.Member;
      import java.util.List;
      import javax.annotation.PostConstruct;
      import javax.enterprise.context.RequestScoped;
      import javax.enterprise.event.Observes;
      import javax.enterprise.event.Reception;
      
      import javax.enterprise.inject.Produces;
      import javax.inject.Inject;
      import javax.inject.Named;
      import javax.persistence.EntityManager;
      import javax.persistence.criteria.CriteriaBuilder;
      import javax.persistence.criteria.CriteriaQuery;
      import javax.persistence.criteria.Root;
      
      @RequestScoped
      public class MemberListProducer {
         @Inject
         private EntityManager em;
      
         private List<Member> members;
      
         // @Named provides access the return value via the EL variable name "members" in the UI (e.g.,
         // Facelets or JSP view)
         @Produces
         @Named
         public List<Member> getMembers() {
            return members;
         }
      
         public void onMemberListChanged(@Observes(notifyObserver = Reception.IF_EXISTS) final Member member) {
            retrieveAllMembersOrderedByName();
         }
      
         @PostConstruct
         public void retrieveAllMembersOrderedByName() {
            CriteriaBuilder cb = em.getCriteriaBuilder();
            CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
            Root<Member> member = criteria.from(Member.class);
            // Swap criteria statements if you would like to try out type-safe criteria queries, a new
            // feature in JPA 2.0
            // criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
            criteria.select(member).orderBy(cb.asc(member.get("name")));
            members = em.createQuery(criteria).getResultList();
         }
      }
      

       

      How can the em.createQuery within retrieveAllMembersOrderedByName succeed?


      2) My second question concerns the login quickstart. There, EJBUserManager looks like this:

       

      package org.jboss.as.quickstarts.login;
      
      import java.util.List;
      import java.util.logging.Logger;
      
      import javax.ejb.Stateful;
      import javax.enterprise.context.RequestScoped;
      import javax.enterprise.inject.Alternative;
      import javax.enterprise.inject.Produces;
      import javax.inject.Inject;
      import javax.inject.Named;
      import javax.persistence.EntityManager;
      
      @Named("userManager")
      @RequestScoped
      @Alternative
      @Stateful
      public class EJBUserManager implements UserManager {
      
         @Inject
         private transient Logger logger;
      
         @Inject
         private EntityManager userDatabase;
      
         private User newUser = new User();
      
         @SuppressWarnings("unchecked")
         @Produces
         @Named
         @RequestScoped
         @Alternative
         public List<User> getUsers() throws Exception {
            return userDatabase.createQuery("select u from User u").getResultList();
         }
      
         public String addUser() throws Exception {
            userDatabase.persist(newUser);
            logger.info("Added " + newUser);
            return "userAdded";
         }
      
         public User findUser(String username, String password) throws Exception {
            @SuppressWarnings("unchecked")
            List<User> results = userDatabase.createQuery("select u from User u where u.username=:username and u.password=:password")
                  .setParameter("username", username).setParameter("password", password).getResultList();
            if (results.isEmpty()) {
               return null;
            } else if (results.size() > 1) {
               throw new IllegalStateException("Cannot have more than one user with the same username!");
            } else {
               return results.get(0);
            }
         }
      
         @Produces
         @RequestScoped
         @Named
         @Alternative
         public User getNewUser() {
            return newUser;
         }
      
      }
      

       

      This class really confused me: EJBUserManager is a stateful EJB (whose state, according to the Java EE Tutorial "is retained for the duration of the client/bean session") and at the same time has a request scope ("The scope of a bean defines the lifecycle and visibility of its instance"). How can these 2 conditions coexist?

      Furthermore, the cheat sheet's comment for getUsers() says that "We create a named producer method that uses JPA to expose all the users currently in the database. This allows JSF to access this list. We also make this request scoped so that the database isn't hit every time we need to display the users list." This is true only within the same HTTP request, isn't it? (so the sentence could be also rewritten as "We also make this request scoped so that the database isn't hit every time we need to display the users list within the same HTTP request")

       

      Thank you for your help!
      bye