1 Reply Latest reply on Apr 3, 2010 11:32 PM by derkd

    Session scoped variabele is at one point null

    derkd

      Hi all,
      I have been struggeling with this issue for over 8 hours now.
      I make use of the Home Pattern. When I register a user the account is saved. I than go to the a page where the user can fill in their personal data (JobSeeker object). The user object is wired with the account with an page action.




      <?xml version="1.0" encoding="UTF-8"?>
      <page xmlns="http://jboss.com/products/seam/pages"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd"
            no-conversation-view-id="/jobseeker/index.xhtml"
            login-required="true">
      
           <begin-conversation join="true" flush-mode="manual"/>
           <action execute="#{jobSeekerAccountHome.wire}"/>
      
           <navigation from-action="#{jobSeekerAccountHome.persist}">
               <end-conversation/>
               <redirect view-id="/jobseeker/my_profile.xhtml"/>
           </navigation>
           
           <navigation from-action="#{jobSeekerAccountHome.update}">
               <end-conversation/>
               <redirect view-id="/jobseeker/my_profile.xhtml"/>
           </navigation>
           
           <navigation from-action="#{jobSeekerAccountHome.remove}">
               <end-conversation/>
               <redirect view-id="/jobseeker/my_profile.xhtml"/>
           </navigation>
      
      </page>





      package nu.anoniemsolliciteren.account.jobseeker;
      
      import java.util.ArrayList;
      import java.util.Date;
      import java.util.List;
      
      import javax.ejb.Remove;
      import javax.persistence.NoResultException;
      import javax.persistence.Query;
      
      import nu.anoniemsolliciteren.account.GenderHome;
      import nu.anoniemsolliciteren.account.preferences.JobSeekerPreferencesHome;
      import nu.anoniemsolliciteren.account.role.Role;
      import nu.anoniemsolliciteren.account.role.RoleHome;
      import nu.anoniemsolliciteren.entities.account.jobseeker.JobSeekerAccount;
      import nu.anoniemsolliciteren.entities.user.JobSeeker;
      import nu.anoniemsolliciteren.entities.user.home.JobSeekerHome;
      import nu.anoniemsolliciteren.validator.AccountValidator;
      
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.Destroy;
      import org.jboss.seam.annotations.Factory;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Out;
      import org.jboss.seam.annotations.Transactional;
      import org.jboss.seam.annotations.datamodel.DataModel;
      import org.jboss.seam.faces.FacesMessages;
      import org.jboss.seam.framework.EntityHome;
      import org.jboss.seam.framework.EntityNotFoundException;
      import org.jboss.seam.log.Log;
      
      @Name("jobSeekerAccountHome")
      public class JobSeekerAccountHome extends EntityHome<JobSeekerAccount> {
           
           /**
            * 
            */
           private static final long serialVersionUID = -2144474684920785886L;
           
           private String lastStateChanged;
           
           @In protected FacesMessages facesMessages;
           @In protected AccountValidator accountValidator;
           
          @In private String ipAddress;
           
           @In(required = false)
           protected Long accountId;
           
           @In(create = true)
           protected JobSeekerPreferencesHome jobSeekerPreferencesHome;
      
           @In(create = true)
           protected RoleHome roleHome;
           @In(create = true)
           protected JobSeekerHome jobSeekerHome;
           @In(create = true)
           protected GenderHome genderHome;
           
           private List<JobSeekerAccount> jobSeekerAccounts;
           
           @Out(required = false, scope = ScopeType.SESSION)
           private Long userId;
      
           
           @Logger
           private static Log log;
           
           /*
            * create the account instance...
            * @see org.jboss.seam.framework.Home#createInstance()
            */
           
           @Override
           protected JobSeekerAccount createInstance() {
                log.debug("createInstance is called, trying to return JobSeekerAccount ");
                JobSeekerAccount jobSeekerAccount = super.createInstance();
                
                return jobSeekerAccount;
           }
           
      //     @Begin(join = true, flushMode = FlushModeType.MANUAL)
           @Override
           @Factory(value = "jobSeekerAccount", scope = ScopeType.CONVERSATION)
           public JobSeekerAccount getInstance() {
                log.debug("getInstance is called, trying to return JobSeekerAccount ");
                JobSeekerAccount jobSeekerAccount = null;
                if(accountId != null && accountId != 0){
                     log.debug("accountId != null " + accountId);
                     setId(accountId);
                     jobSeekerAccount = super.getInstance();
                } else{
                     log.debug("accountId == null ");
                     jobSeekerAccount = super.getInstance();
                }
      
                if(jobSeekerAccount.getDateRegistered() == null) {
                     jobSeekerAccount.setDateRegistered(new java.sql.Date(System.currentTimeMillis()));
                }
                jobSeekerAccount.setDateModified(new java.sql.Date(System.currentTimeMillis()));
                jobSeekerAccount.setIpAddress(ipAddress);
                
                log.debug("returning JobSeekerAccount's username " + jobSeekerAccount.getEmail());
                log.debug("returning JobSeekerAccount's ID " + jobSeekerAccount.getId());
                
                if(jobSeekerAccount.getUser() != null && jobSeekerAccount.getUser().getId() != 0) { 
                     userId = jobSeekerAccount.getUser().getId();
                     log.debug("jobSeekerAccount: userId = " + userId);
                }
                
                return jobSeekerAccount;
           }
      
           
           public JobSeekerAccount getDefinedInstance() {
                return isIdDefined() ? getInstance() : null;
           }
      
           public String validateEntityFound() {
                try {
                     this.getInstance();
                } catch (EntityNotFoundException e) {
                     return "invalid";
                }
      
                return this.isManaged() ? "valid" : "invalid";
           }
           
           public void wire() { // is this necessary, because it is already saved in JobSeekerHome
                log.debug("wire JobSeeker to JobSeekerAccount");
                JobSeeker jobSeeker = jobSeekerHome.getInstance(); 
                if (jobSeeker != null) {
                     getInstance().setUser(jobSeeker);
                }
           }
           
           public boolean isWired() { 
                if (getInstance().getUser() == null) {
                     return false; 
                }
                return true;
           }
           
           public boolean isUsernameAvailable(String userName) {
              return getEntityManager().createQuery(
                  "select a from JobSeekerAccount a where a.userName = :userName")
                  .setParameter("userName", userName)
                  .getResultList().size() == 0;
          }
           
           public boolean isEmailRegistered(String email) {
              return getEntityManager().createQuery(
                  "select a from JobSeeker a where a.email = :email")
                  .setParameter("email", email)
                  .getResultList().size() > 0;
          }
      
           public JobSeekerAccount getJobSeekerAccountByUserName(String userName){
                return (JobSeekerAccount) getEntityManager().createQuery(
                 "select distinct a from JobSeekerAccount a where a.userName = :userName")
                 .setParameter("userName", userName)
                 .getSingleResult();
           }
      
           public String next(){
                return "next";
           }
           
           @Transactional
           public JobSeekerAccount getUserByActivation(String activationKey) {
                Query q = getEntityManager()
                          .createQuery("from JobSeekerAccount u where u.active=0 AND u.activationKey=:activationKey");
                q.setParameter("activationKey", activationKey);
                JobSeekerAccount activatedUser = null;
                try {
                     activatedUser = (JobSeekerAccount) q.getSingleResult();
                } catch (javax.persistence.NoResultException nre) {
                     // safe to ignore ...
                }
                if (activatedUser != null) {
                     activatedUser.setActive(true);
                     activatedUser.setActivationKey(null);
                     accountId = activatedUser.getId();
      //               credentials.setUsername(loginUserId);
                     log.info("UserId {0} activated successfully.", accountId);
                }
                return activatedUser;
           }
           
           public JobSeekerAccount byUserName(String userName) {
                try {
                     Query q = getEntityManager()
                               .createQuery("from JobSeekerAccount u where u.userName = :userName");
                     q.setParameter("userName", userName);
                     return (JobSeekerAccount) q.getSingleResult();
                } catch (NoResultException nre) {
                     log.error("no user found with username "+ userName +" in JobSeekerAccountHome.byUserName(" + userName + ")");
                     log.error("error: " + nre);
                     return null;
                }
           }
           
           protected boolean hasUser(String userName) {
                boolean hasUser = false;
                if (userName != null) {
                     Query q = getEntityManager()
                               .createQuery("select u.userName from JobSeekerAccount u where u.userName = :userName");
                     q.setParameter("userName", userName);
                     hasUser = (q.getResultList().size() > 0);
                }
                return hasUser;
           }
           
           protected Role getRole(String roleName) {
                try {
                     Query q = getEntityManager()
                               .createQuery("from Role r where r.name = :roleName");
                     q.setParameter("roleName", roleName);
                     return (Role) q.getSingleResult();
                } catch (NoResultException nre) {
                     log.error("error" + nre);
                     return null;
                }
           }
           
           @DataModel(scope = ScopeType.PAGE)
           public List<JobSeekerAccount> getJobSeekerAccounts() {
                return jobSeekerAccounts;
           }
      
           public void setJobSeekerAccounts(List<JobSeekerAccount> jobSeekerAccounts) {
                this.jobSeekerAccounts = jobSeekerAccounts;
           }
      
           @Transactional
           @SuppressWarnings("unchecked")
           public void retrieveJobSeekers() {
                log.debug("retrieveJobSeekers is called ");
                jobSeekerAccounts =  (List<JobSeekerAccount>) getEntityManager().createQuery(
                 "from JobSeekerAccount jobSeeker")
                 .getResultList();
                
                if(jobSeekerAccounts == null) {
                     log.debug("jobSeekerAccounts == null ");
                     jobSeekerAccounts = new ArrayList<JobSeekerAccount>();
                }else {
                     log.debug("courses != null, size is: " + jobSeekerAccounts.size());
                     for(JobSeekerAccount jobSeekerAccount : jobSeekerAccounts) {
                          log.debug("jobSeekerAccount name and id");
                          log.debug(jobSeekerAccount.getUserName());
                          log.debug(jobSeekerAccount.getId());
                          log.debug("-----------------");
                     }
                }
           }
           
      //     @SuppressWarnings("unchecked")
           @Override
           @Transactional
           public String persist() {
                log.debug("persist jobSeekerAccount...");
                JobSeekerAccount jobSeekerAccount = getInstance();
      //          IPreferences<JobSeekerPreferences> prefs = jobSeekerPreferencesHome.getInstance();
      //          prefs.setUserId(jobSeekerAccount.getId());
      //          prefs.setCountry("US");
      //          prefs.setProfilePolicy(ProfilePolicy.PRIVATE);
      //          jobSeekerPreferencesHome.persist();
      //          jobSeekerAccount.setPreferences(prefs);
                Role userRole = getRole("jobSeeker");
                if (userRole == null) {
                     log.debug("userRole is null");
                     userRole = roleHome.getInstance();
                     userRole.setName("jobSeeker");
                     userRole.setDescription("General jobSeeker role.");
      
                     log.debug("try to persist userRole");
                     roleHome.persist();
                }
                jobSeekerAccount.addRole(userRole);
                jobSeekerAccount.setDateRegistered(new Date(System.currentTimeMillis()));
      
                lastStateChanged = super.persist();
      //          userId = getInstance().getUser().getId();
                return lastStateChanged;
           }
           
      //     @End
           @Override
           @Transactional
           public String update() {
                log.debug("update jobSeekerAccount...");
                JobSeekerAccount jobSeekerAccount = getInstance();
                log.info("Updating JobSeekerAccount #{account.userName}");
                log.debug("pass bij updaten is: " + jobSeekerAccount.getPasswordHash());
                jobSeekerAccount.setDateModified(new java.sql.Date(System.currentTimeMillis()));
                jobSeekerAccount.setIpAddress(ipAddress);
                lastStateChanged = super.update();
                if(getInstance().getUser() != null && getInstance().getUser().getId() != 0) {
                     userId = getInstance().getUser().getId();
                }
                log.debug("userId: " + userId);
                log.debug("account isManaged? " + isManaged());
                log.debug("account " + jobSeekerAccount.getEmail() + " updated " + lastStateChanged);
                return lastStateChanged;
           }
           
      //     @End
           @Override
           @Transactional
           public String remove() {
                lastStateChanged = super.remove();
                userId = null;
                log.debug("account removed " + lastStateChanged);
                return lastStateChanged;
           }
           
           @Destroy @Remove
           public void destroy(){
                log.debug("jobSeekerAccountHome destroyed");
           }
           
      }







      package nu.anoniemsolliciteren.entities.user.home;
      
      import nu.anoniemsolliciteren.account.jobseeker.JobSeekerAccountHome;
      import nu.anoniemsolliciteren.entities.account.jobseeker.JobSeekerAccount;
      import nu.anoniemsolliciteren.entities.user.JobSeeker;
      
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.Factory;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Transactional;
      import org.jboss.seam.framework.EntityHome;
      import org.jboss.seam.framework.EntityNotFoundException;
      import org.jboss.seam.log.Log;
      
      @Name("jobSeekerHome")
      public class JobSeekerHome extends EntityHome<JobSeeker> {
      
           /**
            * 
            */
           private static final long serialVersionUID = 5589141978796577591L;
           
           private String lastStateChanged;
           @Logger
           private static Log log;
           
           @In(create = true)
           protected JobSeekerAccountHome jobSeekerAccountHome;
           
           @In(required = false)
           private Long userId;
           
           /*
            * create the a user instance...
            * @see org.jboss.seam.framework.Home#createInstance()
            */
           
      //     @Begin(join = true, flushMode = FlushModeType.MANUAL)
           @Override
           @Factory(value = "jobSeeker", scope = ScopeType.CONVERSATION)
           public JobSeeker getInstance() {
                log.debug("getInstance is called, trying to return a jobSeeker ");
                if(userId != null && userId != 0) {
                     log.debug("userId: " + userId);
                     setId(userId);
                }else{
                     log.debug("userId is null: " + userId);
                }
                JobSeeker jobSeeker = super.getInstance();
                return jobSeeker;
           }
           
           @Override
           public Object getId() {
                if(userId == null) {
                     log.debug("userId in getId() is null");
                     return userId;
                }else{
                     log.debug("userId in getId() is null");
                     return super.getId();
                }
           }
      
           public JobSeeker getDefinedInstance() {
                return isIdDefined() ? getInstance() : null;
           }
      
           public String validateEntityFound() {
                try {
                     this.getInstance();
                } catch (EntityNotFoundException e) {
                     return "invalid";
                }
      
                return this.isManaged() ? "valid" : "invalid";
           }
           
           public void wire() {
                log.debug("wire JobSeeker to JobSeekerAccount");
                JobSeekerAccount jobSeekerAccount = jobSeekerAccountHome.getInstance(); 
                log.debug("get jobSeekerAccountID " + jobSeekerAccount.getId());
                
                if (jobSeekerAccount != null) {
                     jobSeekerAccount.setUser(getInstance());
                }
           }
           
           public boolean isWired() { 
                JobSeekerAccount jobSeekerAccount = jobSeekerAccountHome.getInstance(); 
           
                if (jobSeekerAccount != null && jobSeekerAccount.getUser() != null) {
                     return true; 
                }
                return false;
           }
           
      //     @End
           @Override
           @Transactional
           public String update() {
                lastStateChanged = super.update();
      //          userId = getInstance().getId();
                log.debug("jobSeeker is updated and isManaged? " + isManaged());
                log.debug("jobSeeker with userId: " + userId + " is updated");
                return lastStateChanged;
           }
           
      //     @End
           @Override
           @Transactional
           public String remove() {
                lastStateChanged = super.remove();
      //          userId = null;
                log.debug("jobSeeker removed " + lastStateChanged);
                return lastStateChanged;
           }
           
      //     @End
           @Override
           @Transactional
           public String persist() {
                lastStateChanged = super.persist();
      //          userId = getInstance().getId();
                log.debug("jobSeeker persisted and isManaged? " + isManaged());
                log.debug("jobSeeker with userId: " + userId + " is saved");
                return lastStateChanged;
           }
           
      }
      




      The first weird thing is that when I wire the object, an insert occurs. But besides that everything works like expected. Next I want to add a course to the JobSeeker object.




      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
          xmlns:s="http://jboss.com/products/seam/taglib"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:rich="http://richfaces.org/rich"
          template="/layout/jobseeker/template.xhtml">
      
      <ui:define name="body">
      <h:messages globalOnly="true" styleClass="message" errorClass="errormsg" infoClass="infomsg" warnClass="warnmsg" id="globalMessages"/>
          <h:form id="courseForm">
           
              <rich:panel id="addCoursePnl">
                  <f:facet name="header">
                       Add course
                     </f:facet>
                      <s:validateAll>
                     
                          <s:decorate id="titleField" template="/layout/edit.xhtml">
                            <ui:define id="label" name="label">Title:</ui:define>
                            <h:inputText id="title" value="#{course.title}" required="true"/>
                          </s:decorate>
           
                       <s:decorate id="descriptionField" template="/layout/edit.xhtml">
                            <ui:define id="label" name="label">Description:</ui:define>
                            <h:inputTextarea id="description" cols="80" rows="3" value="#{course.description}" required="true"/>
                       </s:decorate>
      
                     </s:validateAll>
                     <div class="actionButtons">
                     <h:commandButton id="NextCourse" value="Save" action="#{jobSeekerHome.persist}" rendered="#{!jobSeekerHome.managed}" disabled="#{!jobSeekerHome.wired}"/>
                     <h:commandButton id="updateCourse" value="Update" action="#{jobSeekerHome.update}" rendered="#{jobSeekerHome.managed}"/>
                     
                     <s:button id="discardResume" value="Discard changes" propagation="end" view="/jobseeker/jobseeker_index.xhtml" rendered="#{jobSeekerHome.managed}"/>
                     <s:button id="cancelResume" value="Cancel" propagation="end" view="/#{empty courseFrom ? 'courseList' :courseFrom}.xhtml" rendered="#{!jobSeekerHome.managed}"/>
                   </div>
              </rich:panel>
              <rich:panel id="listCoursesPnl">
                  <rich:extendedDataTable id="cTable" value="#{courseHome.courses}" var="_course">
                       <rich:column>
                         <f:facet name="header">
                            <h:outputText value="id"/>
                          </f:facet>
                          <h:outputText value="#{_course.id}" />
                       </rich:column>
                        <rich:column>
                          <f:facet name="header">
                            <h:outputText value="title"/>
                          </f:facet>
                          <h:outputText value="#{_course.title}" />
                        </rich:column>
                        <rich:column>
                          <f:facet name="header">
                            <h:outputText value="description"/>
                          </f:facet>
                          <h:outputText value="#{_course.description}" />
                        </rich:column>
                     </rich:extendedDataTable>
                </rich:panel>
      
          </h:form>
      
       </ui:define>
      </ui:composition>





      When I want to add a course to the JobSeeker object I see in the logging that at one point the userId is null. When entering course.xhtml a page action is fired (courseHome.wire() ). The userId is in session scope, how can it be null at some time, I think it has something to do with the scoping but I can't figure it out...




      package nu.anoniemsolliciteren.action;
      
      import java.util.List;
      
      import javax.ejb.Remove;
      
      import nu.anoniemsolliciteren.entities.user.Course;
      import nu.anoniemsolliciteren.entities.user.JobSeeker;
      import nu.anoniemsolliciteren.entities.user.home.JobSeekerHome;
      
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.Destroy;
      import org.jboss.seam.annotations.Factory;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.datamodel.DataModel;
      import org.jboss.seam.faces.FacesMessages;
      import org.jboss.seam.framework.EntityHome;
      import org.jboss.seam.log.Log;
      
      @Name("courseHome")
      public class CourseHome extends EntityHome<Course> {
      
           /**
            * 
            */
           private static final long serialVersionUID = 1928470766987512649L;
      
           private List<Course> courses;
           private String lastStateChange;
           
           @In(create = true)
           private JobSeekerHome jobSeekerHome;
           
           @Logger
           private static Log log;
           
           @In(required = false)
           private Long userId;
           
           @Override
           protected Course createInstance() {
                Course course = super.createInstance();
                //retrieveCourses(); this one is called in the pages.xml
                return course;
           }
           
      //     @Begin(join = true, flushMode = FlushModeType.MANUAL)
           @Override
           @Factory(value = "course", scope = ScopeType.EVENT)
           public Course getInstance(){
                Course course = super.getInstance();
                log.debug("getInstance of Course");
                log.debug("getId() " + course.getId());
                return course;
           }
           
           @DataModel(scope = ScopeType.PAGE)
           public List<Course> getCourses() {
                return courses;
           }
           
           public void setCourses(List<Course> courses) {
                this.courses = courses;
           }
           
           public void retrieveCourses() {
                log.debug("retrieveCourses is called ");
                
                JobSeeker jobSeeker = jobSeekerHome.getInstance();
                courses = jobSeeker.getCourse();
                
           }
           
           public Course getDefinedInstance() {
                return isIdDefined() ? getInstance() : null;
           }
           
           public void wire() {
                log.debug("wire() is called");
                log.debug("userId according injection (session) " + userId);
                JobSeeker jobSeeker = jobSeekerHome.getInstance(); 
                log.debug("get jobSeekerID " + jobSeeker.getId());
                if (jobSeeker.getCourse() != null) {
                     log.debug("jobSeeker.getCourse() != null");
                     jobSeeker.getCourse().add(getInstance());
                }
           }
           
           public boolean isWired() { 
                JobSeeker jobSeeker = jobSeekerHome.getInstance(); 
                if (jobSeeker != null && jobSeeker.getCourse() != null) {
                     for(Course c : jobSeeker.getCourse()){
                          if(c.getId() == getInstance().getId()){
                               log.debug("course is wired");
                               return true; 
                          }else{
                               log.debug("course is not wired");
                               return false;
                          }
                     }
                     
                }
                log.debug("course is not wired");
                return false;
           }
      
      //     @End
           @Override
           public String persist() {
      //          wire();
                lastStateChange = super.persist();
                FacesMessages.instance().add("Course of #{course.title} saved succesfully");
                return lastStateChange;
           }
           
      //     @End
           @Override
           public String update() {
      //          wire();
                lastStateChange = super.persist();
                FacesMessages.instance().add("Course of #{course.title} updated succesfully");
                return lastStateChange;
           }
           
      //     @End
           @Destroy @Remove
           public void destroy(){
                log.debug("courseHome destroyed");
           }
      
      }