4 Replies Latest reply on Dec 15, 2007 1:26 AM by matt.drees

    How to get a child/reference entity to load when the parent

    todd.nash

      I have created a user registration page following the example included with the seam booking example. The only difference is that my User entity has a reference to another entity called account. The user is mapped to an account.

      My User class looks like this:

      /**
       * User
       */
      @Entity
      @Table( name = "t_user", uniqueConstraints = @UniqueConstraint( columnNames = "username" ) )
      public class User implements java.io.Serializable
      {
       private int id;
       private Account account;
      
       [...]
      
      
       @Id
       @Column( name = "id", unique = true, nullable = false )
       @NotNull
       public int getId()
       {
       return this.id;
       }
      
       public void setId( int id )
       {
       this.id = id;
       }
      
       @ManyToOne( fetch = FetchType.LAZY )
       @JoinColumn( name = "account_id" )
       public Account getAccount()
       {
       return this.account;
       }
      
       public void setAccount( Account account )
       {
       this.account = account;
       }
      
      [...]
      }


      My Registration class looks like this:

      @Stateless
      @Name("register")
      public class RegisterAction implements Register
      {
       @In
       private User user;
      
       @PersistenceContext
       private EntityManager em;
      
       @Logger
       private Log log;
      
       public String register()
       {
       List existing = em.createQuery(
       "select username from User where username=#{user.username}")
       .getResultList();
      
       if (existing.size()==0)
       {
       em.persist(user);
       log.info("Registered new user #{user.username}");
       return "/registered.xhtml";
       }
       else
       {
       FacesMessages.instance().add("User #{user.username} already exists");
       return null;
       }
       }
      
      }


      Pretty straight forward. However when the JSF page is loaded and the user clicks on the register button after adding their information, I get a null pointer exception for Account because Seam instantiates the user component, and returns the resulting User entity bean instance to JSF after storing it in the Seam session context, but the Account component is never created.

      I tried instantiating the Account class within my register class and setting the value on the User, but that resulted in a datasource exception when i persisted the user.

      I have tried using the UserHome session bean, but the Account class is never added to the User class.

      How do I go about instantiating and setting the Account on User?

      I am missing something obvious here (could be because it is Friday and I am on my 70th hour). Any help would be appreciated.



        • 1. Re: How to get a child/reference entity to load when the par
          dustismo

          You do realize that your query is returning a list of strings *not* a list of Users?

          This is what I would do..

          List<User> existing = em.createQuery(
           "select u from User u JOIN FETCH u.account where username=#{user.username}")
           .getResultList();
          


          • 2. Re: How to get a child/reference entity to load when the par
            todd.nash

            The query is only checking for existing users with the same username. This should come back with an empty result set if the username is unique.

            I believe that Seam has created and populated the User object with parameters from the JSF page prior to the call to my Register.register().

            My question is how do I get the Account object instantiated with the User object in Seam?

            Thanks

            • 3. Re: How to get a child/reference entity to load when the par
              dustismo

              Ah, I guess I didn't read your code close enough.


              If you want to do something like:

              if (existing.size()==0)
               {
              user.setAccount(new Acount(/*initialization params*/));
               em.persist(user);
               log.info("Registered new user #{user.username}");
               return "/registered.xhtml";
               }
              


              you need to add cascading to your user model.. i.e.
              @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY )
               @JoinColumn( name = "account_id" )
               public Account getAccount()
               {
               return this.account;
               }
              
              



              Hope that helps,
              Dustin

              • 4. Re: How to get a child/reference entity to load when the par
                matt.drees

                 

                "todd.nash@gmail.com" wrote:

                I tried instantiating the Account class within my register class and setting the value on the User, but that resulted in a datasource exception when i persisted the user.


                I think that ought to work...

                What's the exception you get?