0

I have two different paths and this happens only in another one:

  1. SignUp.Xhtml-->SigninUpOkView-->Login.xhtml-->Welcome.xhtml-->UsersController.prepareCreateParty()--->createParty.xhtml-->UsersController.createParty()

  2. SignUp.Xhtml-->SigninUpOkView-->Login.xhtml-->Logout-->Login.xhtml-->Welcome.xhtml-->UsersController.prepareCreateParty()--->createParty.xhtml-->UsersController.createParty()

So what happens: I create a new party-object in controller's method prepareCreateParty() and insert it to the Users-object so that Party is not null when User goes to CreateParty-xhtml page, but it is working only in case 2 where I logout between Signin up and createParty. UserController is a managedBean and UsersController is on SessionScoped. I still have User in Session with name user and I put it there in Login Filter. The cases are identical between Welcome.xhtml---->UsersController.CreateParty() but something really strange happens. I tried to insert default-name to party in createParty-method and in first case, it disappears even if the User object is still there, only Party-property inside the User is NULL. In case two when I logged out and in, it is still there and everything is working fine. What can cause that? I have tried everything and I am starting to be in agony and frustrated.

IN USERS:

@JoinColumn(name = "party_id", referencedColumnName = "party_id")
@ManyToOne
private Party partyId; 

IN USERSCONTROLLER (SessionScoped ManagedBean): public UsersController(Users userEntity) { this.currentUser = userEntity; }

public Users getSelected() {

        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);


        if (currentUser == null) {

            currentUser = (Users) session.getAttribute("user");
            if(currentUser==null){
                currentUser = new Users();
                selectedItemIndex = -1;
            }


        }

public String prepareCreateParty() {

    if (currentUser == null) {
        currentUser = this.getUsersFromSession();
    }

    Party party = new Party();
    party.setName("Testing default name of the party");
    currentUser.setPartyId(party);
    return "createParty";

In CreateParty.xhtml-page:

<p:row>

    <p:column> <h:outputLabel value="#{bundle.CreatePartyLabel_name}" for="name" /></p:column>
    <p:column><p:inputText id="name" value="#{usersController.selected.partyId.name}" title="#{bundle.CreatePartyTitle_name}" required="true" requiredMessage="#{bundle.CreatePartyRequiredMessage_name}"/></p:column>
    <p:column><p:tooltip for="name" showEvent="focus" hideEvent="blur" /></p:column>  
    <p:column><h:outputLabel value="&nbsp;&nbsp;"/></p:column>

</p:row> 

in LoginFilter.doFilter():

if (userPrincipal != null && session.getAttribute("user") == null) {

    UsersFacade test = new UsersFacade();
    Users userEntity = test.findByUsername(userPrincipal.getName());
    session.setAttribute("user", userEntity);
    UsersController userController = new UsersController(userEntity);// Unnecessary constructor call!!

Glassfish 3.1.2 Mojarra 2.1.6 PrimeFaces 3.2 Madness 1.100%

What in the world can cause that, I appreciate you help a lot! I hope that you can figure my explanation out even if the English is what it is. Sami

Matt Handy
  • 29,855
  • 2
  • 89
  • 112
Sami
  • 2,311
  • 13
  • 46
  • 80
  • This is really hard to figure out. These kind of bugs normally can be isolated with a debugger. Debug your code step by step in both cases and find the difference. – Matt Handy Jun 01 '12 at 09:22
  • I made a gum solution: In prepareParty-method I add the party to session and getSelected-method I read it from there and add it to the currentUser and everything is working fine. public Users getSelected() { FacesContext facesContext = FacesContext.getCurrentInstance(); HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false); party = (Party)session.getAttribute("party"); if(party !=null){ currentUser.setPartyId(party); } – Sami Jun 01 '12 at 10:12
  • Now I debugged it, but no solution. Party property inside the CurrentUser just goes to null between createParty() and getSelected()-methods and there is no code between those two. In xhtml-page I am using that selected-method like UsersController.selected...Everything else like username etc is still ok so the currentUser object is not null, just party inside of it. – Sami Jun 01 '12 at 10:48
  • Did you import the correct session scope for your beans from `javax.faces.bean.SessionScoped`? – Matt Handy Jun 01 '12 at 10:52
  • import javax.faces.bean.SessionScoped; Yes, that is in every managedBean Controller classes. – Sami Jun 01 '12 at 11:22
  • Is this the full code? It's not clear how exactly you're registering an user, but I can think of a possible reason that you didn't merge the newly created `Users` object (why is that a plural btw? it represents only one user, right?) properly with JPA. At least, the `if (currentUser == null)` check is strange. Why not a `@ManagedProperty`? The `getUsersFromSession()` could for instance have returned a completely different `Users` instance. – BalusC Jun 01 '12 at 12:01
  • Not the full UserController, but everything what I am using between welcome and createParty pages. You are right that I am not using merge, I am using pure insert (add), but after signing up user have to log in. Btw what happens to currentUser created in singing up process? Is it still in memory even if the user log in? That can be the cause if so, because everything is working if I log out once between (like in case 2). I haven't read about managed properties,so I don't know how to use them :), maybe I should read about it.Users is in plural cause Netbeans were complaining that it is reserved – Sami Jun 01 '12 at 12:16
  • Because of BalusC comment I started to check what is happening in my servlet filter and I think that there is the culprit. After sign up is there still the same session? I am not invalidating it either between sign up and log in. – Sami Jun 01 '12 at 12:35
  • And it starts to work right when I added session.invalidate() after sign up, between the SigninUpOkView-->Login.xhtml. Don't ask me why :( – Sami Jun 01 '12 at 13:45

1 Answers1

1

I think this problem is caused because you ultimately end up with two different instances of Users object (I'd rename it to User btw, it represents only one user, right?), one as user in the session scope which is been set by the filter and another one as currentUser property of the UserController which is been set during the signup. You're in getSelected() checking if the currentUser isn't null and thus after all not using the one set by the filter. Invalidating the session clears the currentUser and hence it works "as expected".

If you do a sessionMap.put("user", user) during signup, then I'd suggest to instead use

@ManagedProperty("#{user}")
private Users user; // +setter

in managed beans wherever necessary so that you can ensure having the one and the right instance of the currently logged in user. Note that the #{user} doesn't necessarily need to be a @ManagedBean. EL just scans the request/view/session/application scopes by the attribute name.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Yes, users represents only one user. Netbeans was saying that User was reserved word, so I changed it to Users. How sessionMap differs from normal HttpSession? I've got a managed bean controllers and selected always represents the final JPA-object/bean like Users so there is no properties on managed Object except inside of that "currentObject". I read that design from some book or tutorial, any good or piece of something? Pros and cons? What you think? Thanks a lot again for helping me for everyone! – Sami Jun 01 '12 at 15:42
  • BTW, any good examples what is the best way to initialize session after login? – Sami Jun 01 '12 at 15:45
  • The session map is a JSF abstraction of HTTP session attributes so that you do not need to import raw `javax.servlet` in your JSF code (which is usually considered poor practice). Whatever you put in the session map, will *actually* get set as a session attribute. The same applies to request map <--> request attributes and application map <--> servletcontext attributes. As to initializing session after login, just put the user in session map by `sessionMap.put("user", user)`. It'll be available as a session attribute in filter and be available as `#{user}` in EL. It's all the same instance. – BalusC Jun 01 '12 at 16:08
  • Thanks, I'll change that. Any comment about my "design"? @ManagedBean(name = "usersController") (AT)SessionScoped public class UsersController implements Serializable { private Users currentUser; //JPA-bean private DataModel items = null; (AT)EJB private com.party.sessionBeans.UsersFacade ejbFacade; private PaginationHelper pagination; And there is plenty of stuff inside the User, so this might be a heavy memory eater? When User is in session, then there is every property as well like Party... – Sami Jun 01 '12 at 16:15
  • You should indeed try to minimize the `@ManyToOne` properties in `Users` to only the absolutely necessary ones which is used in every request, such as roles and maybe some global settings. Assuming that information about `List` is not absolutely necessary in every request, then load it on a per-request/view basis instead based on the `@ManagedProperty("#{user}")`. – BalusC Jun 01 '12 at 16:44