5 Replies Latest reply on Jul 13, 2006 7:47 PM by joff

    Is this the correct way to go about this?

    joff

      We are developing a Seam application using JBoss Seam current CVS, Sun JSF 1.2, and Facelets.

      We currently have this type of model:

      Our EJB3 entities are:
      CompanyCustomerUser

      Company has many customers, who in turn have many users.

      We have developed what we are calling "DAOs" or Data Access Objects, so that we can pull out (for example) a List of all Company objects (this is outside of any form context so no EJB3 is currently involved).

      For example, our CompanyDAO implementation looks like this:

      @Name("dao_company")
      public class CompanyDAOImpl implements Serializable, CompanyDAO {
      
       private static final long serialVersionUID = 1L;
      
       @In(create=true)
       private transient EntityManager entityManager;
      
       @SuppressWarnings("unchecked")
       @WebRemote
       public List<Company> getCompanies() {
       Query query = entityManager.createQuery("FROM Company company");
       return (List<Company>) query.getResultList();
       }
      }


      We would like to add a getCompanyByID() method to this class. However, because this method needs to be called from the JSF layer, we have to pass in the parameter as a field annotated with @RequestParameter. When we do this, the getCompanies() method (which does not use the annotated parameter) can no longer be called unless this field is filled in.

      We have two questions:
      Is this the correct way to be doing this type of "pull" data access? We have looked at the "Blog" example, but it does not seem as complex as what we are trying to do.
      Is it possible to have multiple @RequestParameter fields on a JavaBean like the one above, which do not all have to be populated when any given method (which may or may not use them) is called?

        • 1. Re: Is this the correct way to go about this?
          bfo81

           

          "joff" wrote:
          We have two questions:
          <ul><li>Is this the correct way to be doing this type of "pull" data access? We have looked at the "Blog" example, but it does not seem as complex as what we are trying to do.</li>
          <li>Is it possible to have multiple @RequestParameter fields on a JavaBean like the one above, which do not all have to be populated when any given method (which may or may not use them) is called?</li></ul>

          * The examples are intentionally kept quite simple, so don't wonder why your real-life app seems to be "overcomplex". It surely isn't. DAOs are a very good way to retrieve data from a database, as long as they are used in many other classes. If there is only one class performing a certain db query (and no other predictable scenario in the future) I wouldn't create a DAO cause this only blows up the complexity. If there's no need for something and you still use it, then it's "pattern madness". But that's just my opinion and there surely are other opinion about this, too ;).

          * Unfortunately there's no attribute "required" for @RequestParameter like @In or @Out have, and so it always must be set when invoking one of the methods of your bean. I don't know exactly how your app works, but maybe you can use @In(required=false) instead of @RequestParameter? I even believe that this is the way it was meant to in Seam. RequestParameter seems to me to be just a little... well... accomodation to the old fashioned way of passing data from one page to another;).

          • 2. Re: Is this the correct way to go about this?
            gavin.king

             

            @RequestParameter String companyId;
            
            public Company getCompany()
            {
             return getCompany(companyId);
            }
            
            public Company getCompany(String companyId)
            {
             return entityManager.find(Company.class, companyId);
            }


            Note that if there is no value for an @RequestParameter, it will be null, it will not throw an exception (yes, this is inconsistent with @In and is arguably a wart).

            • 3. Re: Is this the correct way to go about this?
              joff

              Upon closer inspection, we found our problem: the parameter was being passed in as a String, and we were expecting a long. So we now have:

              @RequestParameter
              private String companyID;
              
              public Company getCompany() {
               if(companyID != null) {
               return (Company) entityManager.find(Company.class,
               Long.decode(companyID));
               }
               return null;
              }


              Everything seems to be working happily now - thanks!


              • 4. Re: Is this the correct way to go about this?
                gavin.king

                Seam should automagically do the type conversion from String to Long ...

                are you sure that was the problem?

                • 5. Re: Is this the correct way to go about this?
                  joff

                  The problem was when the request parameter wasn't passed in via the URL, i.e. when we use the getCustomers() method, which doesn't use that parameter.

                  We were actually expecting a primitive long (I should have checked my capitalization in my previous post), which obviously cannot be made null by Seam when it isn't passed in.

                  We're now expecting a Long object instead, and it works :-)