10 Replies Latest reply on Oct 4, 2012 2:33 AM by Martin Kouba

    can not set an entity property through selectOneMenu

    surajmundada Newbie

      Hi,

       

      I am using  Seam 2.2.0 GA with Jboss AS 4.2.

       

      I am trying to display a list and set the selected value from list in an entity and persist it. Following are code snippets:

       

                <s:decorate id="productCategoryField" template="layout/edit.xhtml">

                            <ui:define name="label">Product Category</ui:define>

                         <h:selectOneMenu id="menuProductCategory" value="#{retaileraccount.productCategory}">

                                    <s:selectItems value="#{regsiterRetailer.listProductCategory}" var="pCategory" label="#{pCategory.productCategoryName}" noSelectionLabel="Please Select"/>

                               </h:selectOneMenu>           

                  </s:decorate>

       

       

      Entities are as follow:

       

       

      @Entity

      @Name("retaileraccount")

      @Scope(ScopeType.SESSION)

      @Table(name="retailer_Account")

      public class RetailerAccount implements Serializable

      {

                @Id @GeneratedValue

                private int retailerId;

         

          @ManyToOne()

          private ProductCategory productCategory;

       

       

       

      @Entity

      @Name("productcategory")

      @Scope(ScopeType.SESSION)

      @Table(name="product_category")

      public class ProductCategory implements Serializable { 

       

                @Id @GeneratedValue

                private Long productCategoryId;

         

                private String productCategoryName;

              private String productCategoryDetails;

       

       

      Action

       

       

      @Stateless

      @Name("regsiterRetailer")

      public class RegsiterRetailerActionBean implements RegsiterRetailerAction {

          @Logger private Log log;

       

          @In StatusMessages statusMessages;

         

           @In("retaileraccount")

          RetailerAccount retailerAccount;

       

          @PersistenceContext

          private EntityManager em;

         

          public RetailerAccount getRetailerAccount() {

                          return retailerAccount;

                }

       

                public void setRetailerAccount(RetailerAccount retailerAccount) {

                          this.retailerAccount = retailerAccount;

                }   

         

          public String regsiter() {

              // implement your business logic here

              log.info("regsiterRetailerAction.regsiterRetailerAction() action called");

             

              List existingList = em.createQuery("select establishmentName from RetailerAccount " +

                                                                                              "where establishmentName = #{retailerAccount.establishmentName}").getResultList();

             

              if(existingList.size() != 0) {

                        FacesMessages.instance().add("Shop  #{retailerAccount.establishmentName} already exists");

                  return null;

              }

             

              em.persist(retailerAccount);

             

              log.info("Registered new establishment #{retailerAccount.establishmentName}");

              return null;

          }

       

          public List getListProductCategory() {

                          List listProductCategory = em.createQuery("select productCategory from ProductCategory productCategory").getResultList();

       

                          System.out.println("here in getListProductCategory");

       

                          return listProductCategory;

                }

      }

       

       

      SQL schema:

       

       

      CREATE TABLE `product_category` (

        `product_category_id` int(11) NOT NULL auto_increment,

        `product_category_name` varchar(250) NOT NULL default '',

        `product_category_details` varchar(250) default NULL,

        PRIMARY KEY  (`product_category_id`)

      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

       

       

      CREATE TABLE `retailer_account` (

        `retailer_id` int(11) NOT NULL auto_increment,

        `product_category` int(11) NOT NULL default '0',

        PRIMARY KEY  (`retailer_id`),

        KEY `product_category` (`product_category`),

        CONSTRAINT `retailer_account_ibfk_1` FOREIGN KEY (`product_category`) REFERENCES `product_category` (`product_category_id`)

      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

       

       

      When I run this, I get error as

       

      Property 'productcategory' not found on type com.shoppingthreads.retailer.entity.RetailerAccount    

       

      I cross checked with sample examples and seems everything is correct.

       

      Can somebody help with identifying the problem and solution?

       

      Thanks.

      Suraj

        • 1. Re: can not set an entity property through selectOneMenu
          Martin Kouba Master

          Hi,

          just a dumb question... do you have appropriate getters/setters on RetailerAccount component?

          • 2. Re: can not set an entity property through selectOneMenu
            surajmundada Newbie

            all getter-setters are in place .... i posted only half code snippets to give idea about entities and its attributes.

             

            Any help?

             

            Thanks.

            • 3. Re: can not set an entity property through selectOneMenu
              Martin Kouba Master

              Hm, have no idea. I would also doublecheck the property name... you have #{retaileraccount.productCategory} in your xhtml snippet, but the error description "Property 'productcategory' not found on type..." looks like the expression #{retaileraccount.productcategory} is used...

              • 4. Re: can not set an entity property through selectOneMenu
                surajmundada Newbie

                I changed changed the variable name from "retailerAccount" to " retaileraccount" in my session bean and #{retaileraccount.productCategory} to #{retaileraccount.productcategory} in xhtml. It solved the problem.

                 

                But this is a work around only.

                 

                I want to understand what is the correct way of using seam components? Is it necessary to have variable name and seam name same? If variable name and seam name not required to be same, which name should be used to access that component at other places? variable name or seam name?

                • 5. Re: can not set an entity property through selectOneMenu
                  Martin Kouba Master

                  Firstly the EL #{retaileraccount.productCategory} does not result in lookup of your session bean component RegsiterRetailerActionBean. It gets the entity bean component RetailerAccount and tries to invoke getProductCategory() method on it. If #{retaileraccount.productcategory} works for you, the getter getProductcategory() is declared. Secondly it's not required to have the same variable name and component name, but I think it's a good practice. In any case your original code @In("retaileraccount") RetailerAccount retailerAccount should work... and I would bet it works ...

                  • 6. Re: can not set an entity property through selectOneMenu
                    surajmundada Newbie

                    Hi,

                     

                    After lot of searching and going through sample examples and forum discussions, I could solve most of the issues wrt to displaying selectOneMenu. It displays correctly and sets selected value correctly in bean variable.

                     

                    But not able to persist. Giving me following error:

                     

                    22:31:03,265 WARN  [JDBCExceptionReporter] SQL Error: 1216, SQLState: 23000

                    22:31:03,265 ERROR [JDBCExceptionReporter] Cannot add or update a child row: a foreign key constraint fails

                     

                     

                    My insert query looks like this;

                     

                    [code]

                    insert into retailer_Account (establishment_name, owner_name, vat_tan, address_line_1, address_line_2, address_line_3, city, pincode, contact_person, contact_number_mobile, contact_number_landline, retailer_subscription_type) values  (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

                     

                    [/code]

                     

                    Entities:

                     

                    [code]

                    @Entity

                    @Name("productcategory")

                    @Scope(ScopeType.SESSION)

                    @Table(name="product_category")

                    public class ProductCategory implements Serializable {

                              private static final long serialVersionUID = 3524419401213908553L;

                     

                              @Id @GeneratedValue

                              @Column(name="product_category_id")

                              private Long productCategoryId;

                     

                              @Column(name="product_category_name")

                              private String productCategoryName;

                     

                              @Column(name="product_category_details")

                        private String productCategoryDetails;

                     

                     

                     

                    @Entity

                    @Name("retaileraccount")

                    @Scope(ScopeType.SESSION)

                    @Table(name="retailer_Account")

                    public class RetailerAccount implements Serializable {

                              private static final long serialVersionUID = 3647321669677100358L;

                     

                              @Id @GeneratedValue

                              @Column(name="retailer_id")

                              private int retailerId;

                     

                              @Column(name="establishment_name")

                        private String establishmentName;

                       

                              @Column(name="owner_name")

                              private String ownerName;

                       

                              @Column(name="vat_tan")

                              private String vatTan;

                       

                              @Column(name="address_line_1")

                              private String addressLine1;

                       

                              @Column(name="address_line_2")

                              private String addressLine2;

                       

                              @Column(name="address_line_3")

                              private String addressLine3;

                       

                              @Column(name="city")

                              private String city;

                       

                              @Column(name="pincode")

                              private short pincode;

                       

                              @ManyToOne()

                        @JoinColumn(name="product_category_id", updatable=false, insertable=false)

                        private ProductCategory productcategory;

                       

                        @Column(name="contact_person")

                        private String contactPerson;

                       

                        @Column(name="contact_number_mobile")

                        private int contactNumberMobile;

                       

                        @Column(name="contact_number_landline")

                        private int contactNumberLandline;

                       

                        @Column(name="retailer_subscription_type")

                        private String retailerSubscriptionType;

                     

                    [/code]

                     

                    Action:

                    [code]

                     

                    @Stateless

                    @Name("regsiterRetailer")

                    public class RegsiterRetailerActionBean implements RegsiterRetailerAction {

                              @Logger private Log log;

                        @In StatusMessages statusMessages;

                       

                              @In("retaileraccount")

                        RetailerAccount retailerAccount;

                     

                        @In

                        private EntityManager entityManager;

                       

                        @Out(required=false)

                        public List<ProductCategory> listProductCategory;

                       

                        public ProductCategory productCategory;

                       

                        public RetailerAccount getRetailerAccount() {

                                             return retailerAccount;

                                   }

                     

                              public void setRetailerAccount(RetailerAccount retailerAccount) {

                                             this.retailerAccount = retailerAccount;

                                   }   

                       

                        public String regsiter() {

                            // implement your business logic here

                            log.info("regsiterRetailerAction.regsiterRetailerAction() action called");

                           

                            List existingList = entityManager.createQuery("select establishmentName from RetailerAccount " +

                                                                                                            "where establishmentName = #{retailerAccount.establishmentName}").getResultList();

                           

                            if(existingList.size() != 0) {

                                           FacesMessages.instance().add("Shop  #{retailerAccount.establishmentName} already exists");

                                return null;

                            }

                           

                            retailerAccount.setProductCategory(productCategory);

                           

                            entityManager.persist(retailerAccount);

                           

                            log.info("Registered new establishment #{retailerAccount.establishmentName}");

                            //return "/retailerAccountList.xhtml";

                            return null;

                        }

                     

                       @Factory("listProductCategory")

                        public void populateListProductCategory() {

                            listProductCategory = entityManager.createQuery("select productCategory from ProductCategory productCategory").getResultList();

                                   }

                     

                    public ProductCategory getProductCategory() {

                                        return productCategory;

                              }

                     

                      public void setProductCategory(ProductCategory selectedProductCategory) {

                                        this.productCategory = selectedProductCategory;

                              }

                     

                      public List<ProductCategory> getListProductCategory() {

                                        return listProductCategory;

                              }

                     

                    public void setListProductCategory(List<ProductCategory> listProductCategory) {

                                        this.listProductCategory = listProductCategory;

                              }

                    [/code]

                     

                     

                    What I am doing wrong? Any issue with entity definitions?

                     

                    Regards,

                    Suraj

                    • 8. Re: can not set an entity property through selectOneMenu
                      Martin Kouba Master

                      How does the "retailer_Account" table look like (DDL)?

                      • 9. Re: can not set an entity property through selectOneMenu
                        surajmundada Newbie

                        Hi,

                         

                        retailer_account is as follow:

                         

                        CREATE TABLE `retailer_account` (

                          `retailer_id` int(11) NOT NULL auto_increment,

                          `establishment_name` varchar(250) NOT NULL default '',

                          `owner_name` varchar(250) NOT NULL default '',

                          `vat_tan` int(11) NOT NULL default '0',

                          `address_line_1` varchar(250) NOT NULL default '',

                          `address_line_2` varchar(250) default NULL,

                          `address_line_3` varchar(250) default NULL,

                          `city` varchar(50) NOT NULL default '',

                          `pincode` smallint(6) default NULL,

                          `product_category` int(11) NOT NULL default '0',

                          `contact_person` varchar(250) NOT NULL default '',

                          `contact_number_mobile` int(11) NOT NULL default '0',

                          `contact_number_landline` int(11) NOT NULL default '0',

                          `retailer_subscription_type` varchar(50) default NULL,

                          PRIMARY KEY  (`retailer_id`),

                          KEY `product_category` (`product_category`),

                          CONSTRAINT `retailer_account_ibfk_1` FOREIGN KEY (`product_category`) REFERENCES `product_category` (`product_category_id`)

                        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

                         

                        product_category:

                         

                        CREATE TABLE `product_category` (

                          `product_category_id` int(11) NOT NULL auto_increment,

                          `product_category_name` varchar(250) NOT NULL default '',

                          `product_category_details` varchar(250) default NULL,

                          PRIMARY KEY  (`product_category_id`)

                        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

                        • 10. Re: can not set an entity property through selectOneMenu
                          Martin Kouba Master

                          I think the problem is in the way the manyToOne association productcategory is defined. In DDL product_category is NOT NULL with default value 0.  By specifying @JoinColumn(name="product_category_id", updatable=false, insertable=false) you omit the association from the insert query (as you noted). So the product_category column is defaulted to 0 and there is probably no record in product_category table with PK 0.